• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Pytanie odnośnie funkcji C++

Object Storage Arubacloud
+1 głos
388 wizyt
pytanie zadane 25 maja 2021 w C i C++ przez Drożdżówka Obywatel (1,870 p.)
Czy w C++ da się zrobić tablicę funkcji?

Np. coś takiego:

void func()[100];

void func()[15]{

cout << "1";

}

 

int main(){

func()[15];

}
komentarz 25 maja 2021 przez wizarddos Nałogowiec (25,930 p.)

Wstaw kod do bloczka

no i co ten kod miałby robić. Tablice funkcji?

3 odpowiedzi

+2 głosów
odpowiedź 25 maja 2021 przez adrian17 Ekspert (345,160 p.)
wybrane 29 maja 2021 przez Drożdżówka
 
Najlepsza

Tablicę wskaźników na funkcje - da się. Tylko niezbyt taką skłądnią (ogólnie chyba powinieneś powtórzyć używanie tablic) :) Na przykład:

void func1(){ cout << "1"; }
void func2(){ cout << "2"; }
void func3(){ cout << "3"; }

using MyFuncType = void();
const MyFuncType *FUNCS[5] = { func1, func2, func3, func1, func2 };
 
int main(){
    FUNCS[3]();
}

 

komentarz 25 maja 2021 przez Drożdżówka Obywatel (1,870 p.)
Ciekawe, spróbuję tego użyć.
+1 głos
odpowiedź 25 maja 2021 przez TOM_CPP Pasjonat (22,640 p.)

Można użyć wyrażeń lambd jako funkcji umieszczając to w osłonie (wrapper) std::function<> + std::vector jako kontener na dane.

#include <iostream>
#include <vector>
#include <functional>

using namespace std;

int main()
{
    vector<function<int(int)>> functions = { []( int a ){ return a+a; },
                                             []( int a ){ return a*a; },
                                             []( int a ){ return 3*a; } };


    for( const auto& funct : functions ) cout << funct(6) << endl;
}

 

komentarz 25 maja 2021 przez mokrowski Mędrzec (155,700 p.)
Jasne. Tylko to kosztuje podwójne virtual bo pod spodem jest idiom wymazywania typu (type erasure).

Popatrz ile masz kodu asemblerowego tu: https://godbolt.org/z/x3njYW78Y

I tu: https://godbolt.org/z/r4dKa3zYP
1
komentarz 25 maja 2021 przez TOM_CPP Pasjonat (22,640 p.)

Po zmianie kontenera na std:array oraz kompilacja z flagą -O3 skraca kod asemblera do 111 linijek.

Jeżeli sytuacja nie wymaga użycia gołych wskaźników na funkcję ( n.p. istotne względy wydajnościowe ), to wolę wariant z bardziej "elastycznym" kodem, który jest dla mnie łatwiejszy w późniejszym utrzymaniu/serwisowaniu.

komentarz 26 maja 2021 przez adrian17 Ekspert (345,160 p.)
edycja 26 maja 2021 przez adrian17

to wolę wariant z bardziej "elastycznym" kodem, który jest dla mnie łatwiejszy w późniejszym utrzymaniu/serwisowaniu.

Bardziej ograniczony kod może być łatwiejszy w utrzymaniu, analizowaniu - bo wiadomo dokładnie czego nie może zrobić.

No i ogólnie YAGNI. Jeśli coś jest prostsze (i przy okazji wydajniejsze) to z natury jest lepszym defaultem od czegoś cięższego "bo może kiedyś będzie potrzebne".

Nie bez powodu na przykład nowsze języki lubią const-by-default, nawet jeśli nie pomaga im to w wydajności.

BTW:

skraca kod asemblera do 111 linijek.

To wciąż jest szalenie dużo jak na kod który jest no-opem ;)

komentarz 26 maja 2021 przez mokrowski Mędrzec (155,700 p.)
edycja 26 maja 2021 przez mokrowski

Cóż. Ja potrzebuję poważniejszego powodu do użycia std::function niż przykład z 3 funkcjami. Właśnie biorąc pod uwagę objętość i wydajność kodu (a także ścisłe typowanie które i tak występuje w wersji ze wskaźnikiem). W niekorzystnych warunkach (oba wskaźniki w RAM i brak reprezentacji w cache), tracisz bardzo na wydajności. Nie wspominając już o objętości kodu. Ta ostatnia eliminuje (w zasadzie) zastosowanie w embedded gdzie zawsze poważnie rozważa się użycie funkcji wirtualnych (jawnych czy nie).

Takie same historie obecnie występują także np. przy stosowaniu zakresów (range). Kod puchnie niepomiernie i bardzo spada jego wydajność. Co nie znaczy że nie należy ich znać i tam gdzie to ma sens, używać.

Ogólnie te abstrakcje są obecnie jeszcze zbyt dalekie dla "kompetencji dzisiejszych kompilatorów" :) Wygodne, zgadzam się ale IMHO trzeba znać koszt tego luksusu :)

BTW: Każda lambda jest oddzielnym typem. Popatrz co wyprawiasz :) https://cppinsights.io/lnk?code=I2luY2x1ZGUgPGFycmF5PgojaW5jbHVkZSA8ZnVuY3Rpb25hbD4KIAp1c2luZyBuYW1lc3BhY2Ugc3RkOwogCmludCBtYWluKCkgewogICAgYXJyYXk8ZnVuY3Rpb248aW50KGludCk+LCAzPiBmdW5jdGlvbnMgPSB7IFtdKCBpbnQgYSApeyByZXR1cm4gYSthOyB9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbXSggaW50IGEgKXsgcmV0dXJuIGEqYTsgfSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW10oIGludCBhICl7IHJldHVybiAzKmE7IH0gfTsKIAogCiAgICBpbnQgc3VtID0gMDsKICAgIGZvciggY29uc3QgYXV0byYgZnVuY3QgOiBmdW5jdGlvbnMgKSB7CiAgICAgICAgc3VtICs9IGZ1bmN0KDQyKTsKICAgIH0KICAKICAgIHJldHVybiBzdW07Cn0=&insightsOptions=cpp17&std=cpp17&rev=1.0

komentarz 26 maja 2021 przez adrian17 Ekspert (345,160 p.)
edycja 26 maja 2021 przez adrian17

Każda lambda jest oddzielnym typem. Popatrz co wyprawiasz :)

(To akurat nie jest problem, lambda nic nie łapiąca jest trywialnie konwertowalna na wskaźnik na funkcję, który kompilator jest w stanie inline'ować. Bardziej złożone lambdy też się dają inline'ować; zazwyczaj staje się to zero-cost abstraction. Prawdziwą barierą optymalizacji jest std::function.)

komentarz 26 maja 2021 przez TOM_CPP Pasjonat (22,640 p.)

Tutaj jest przedstawiony ciekawy test/artykuł na temat wydajności std::function.

0 głosów
odpowiedź 25 maja 2021 przez Antytalent Początkujący (470 p.)

Można zrobić funkcję z parametrem w postaci tablicy

void funkcja(int tablica[])
{
    //dzialanie funkcji
}

 

komentarz 25 maja 2021 przez Whiskey_Taster Pasjonat (15,610 p.)

Tak, jak najbardziej, jednak tutaj chodzi o konkretnie tablicę funkcji, czyli elementami tablicy miałyby być funkcje. Już w jednym poście adrian17 pokazał, że można stworzyć taką tablicę, tylko zamiast funkcji mamy wskaźniki na funkcje. 

Jak się dopiero co uczysz, to polecam książkę "Język C++. Szkoła programowania" Stephena Praty, wydanie VI. Całe po polsku i w sam raz na start :) 

komentarz 25 maja 2021 przez NewEraOfPeace Gaduła (4,790 p.)
Typ parametru to nie tablica, a wskaźnik

Podobne pytania

0 głosów
1 odpowiedź 136 wizyt
pytanie zadane 5 sierpnia 2020 w Python przez Marak123 Stary wyjadacz (11,190 p.)
–3 głosów
0 odpowiedzi 178 wizyt
pytanie zadane 15 września 2019 w Sprzęt komputerowy przez Kubserq Nowicjusz (120 p.)
0 głosów
1 odpowiedź 239 wizyt
pytanie zadane 23 grudnia 2016 w Ruby przez Newperty Początkujący (280 p.)

92,621 zapytań

141,477 odpowiedzi

319,817 komentarzy

62,005 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...