Template programozás, visszatérési érték megjelölés auto nélkül...

 ( p000t | 2017. május 22., hétfő - 9:35 )

Sziasztok! Nem vagyok fejlesztő, csak kíváncsi. Valaki tudna nekem segíteni abban, hogy a lenti linken található kód 12-13. sorát hogyan kell értelmezni? Túrom a netet már órák óta, de nem találtam még csak hasonlót sem a using és a trailing return type itteni használatához.

Az elméletem az, hogy az overloaded struct becsomagolja amit kap, és meghívja annak () operátorát. Az overloaded fv. pedig arra kell, hogy létrehozza a megfelelő specializációkat. De miért nem kell az auto a fv. elé? A szabvány melyik részein kell ezt valyon keresni?

http://coliru.stacked-crooked.com/a/bb14d29542850e56

Köszi!
P.

Hozzászólás megjelenítési lehetőségek

A választott hozzászólás megjelenítési mód a „Beállítás” gombbal rögzíthető.

Most látom, hogy "valyon"-t írtam. Ezer bocs! Nyugodtan javítsatok ki, ha még hibáztam...

p00t

Szerintem : http://en.cppreference.com/w/cpp/language/parameter_pack
Ha nem érthető pontosan akkor kérdezz részletesebben és akkor válaszolok arra a részletre.
--
www.autosys.hu

12. sor: a using-gal csak beemeled az overloaded struct 'szkopjaba' az operator() fuggvenyeket (amik a 43., 44., 45. sorban vannak). Egy ilyen visitort irhatsz varazslas nelkul is. Peldaul:

struct myvisitor {
void operator()(auto arg) { std::cout << arg << ' '; }
void operator()(double arg) { std::cout << std::fixed << arg << ' '; }
void operator()(const std::string& arg) { std::cout << std::quoted(arg) << ' '; }
};

Az std::visit az, ami meghivja az operator() fuggvenyeket (Callable concept).

Ez nem trailing return type, hanem "class template deduction": http://en.cppreference.com/w/cpp/language/class_template_deduction (egeszen pontosan a "User-defined deduction guides" szekcio kell neked).

Ez technika akkor kell, amikor 'variant' osztalyt implementalsz (trendi neven 'algebraic data type'). c++-ban nincs tipus alapu 'switch' utasitas (pl. haskell-ben es rust-ban van). Ugye a variant a tulajdonkeppen nehany osztalybol kepzett unio (pl. mondhatod azt, hogy az erteked az "vagy egy int, vagy egy double vagy egy string" -> variant). Ez igy meg nem tul nehez, a gond ott jon, hogy kell egy konstrukcio:

Ez most pszeudokod:

variant v;
switch (v) {
case int: ....;break;
case double: ....;break;
case std::string: ...;break;
}

Ez C++-ban nem igazan lehetseges (leven a variant tisztan konyvtari megoldas, nincs direkt nyelvi tamogatasa). Viszont helyette meg lehet csinalni, hogy van egy osztaly, aminek overloaded operator() metodusai vannak es a megfelelo tipusokat fogadjak (ezeket hivjak visitoroknak), es igy emulaljak a switch utasitast (a kulonbozo esetek kulonbozo metodusokat hivnak majd, es ez igy statikusan ellenorizheto/tipusbiztos). Az 'overloaded' template a tealtalad linkelt kodban annyit csinal, hogy fog egy halom funktort es ezeket osszekombinalja egy visitorba.

Ami miatt azt a template deduction-t meg kell jatszani, az az (mint a main fv. kodja is mutatja), hogy a visitorokat tobbnyire lambdakbol epitik fel (igy imitalja legjobban a switch utasitast). A problema annyi, hogy a lambdak nincs konnyen 'megfejtheto' tipusa (van neki, csak nem tudjuk a nevet), marpedig template-et peldanyositani, csak a tipusparameterek ismereteben lehet. Igazabol annyi a nyeremeny, hogy nem kell kiirni tipusokat, amiket a template peldanyositasahoz hasznalsz, igy a kod kicsit olvashatobb lesz es konnyebb modositani is.

Köszi a válaszokat! Még emésztem...

p00t