5

Więc this example od: http://en.cppreference.com/w/cpp/utility/variant/visit deklaruje typ specjalistycznego:Co to jest typ Ta struktura dziedziczy po?

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; 
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; 

która jest skonstruowana jako wartość R tutaj:

std::visit(overloaded { 
    [](auto arg) { std::cout << arg << ' '; }, 
    [](double arg) { std::cout << std::fixed << arg << ' '; }, 
    [](const std::string& arg) { std::cout << std::quoted(arg) << ' '; }, 
}, v); 

próbuję dowiedzieć się, jak to działa. Jaki typ dziedziczy tutaj overloaded? Wygląda jak tablica lambd, ale nie widzę, jak to by miało operator(). Czy ktoś może wyjaśnić, w jaki sposób działa tu dziedziczenie?

+3

Jeśli masz ponad 10 tys. Widzisz, właśnie wypróbowałem to pytanie: https://stackoverflow.com/q/44414238/2642059 @BaummitAugen pomógł mi rozpoznać dziedziczenie. Więc myślę, że teraz zadaję właściwe pytanie. –

Odpowiedz

6

overloaded dziedziczy z każdego lambda indywidualnie, a każdy lambda ma operatora połączenia. Dlatego należy utworzyć strukturę, która ma wszystkich operatorów wywołań w jednym zestawie przeciążenia. Dopóki nie są niejednoznaczne, właściwa zostanie wybrana automatycznie.

można sobie wyobrazić o zmiennej liczbie argumentów szablonu rozszerzyć do

struct overloaded : 
    // inherits from 
    decltype([](auto arg) { std::cout << arg << ' '; }), 
    decltype([](double arg) { std::cout << std::fixed << arg << ' '; }), 
    decltype([](const std::string& arg) { std::cout << std::quoted(arg) << ' '; }) 

    // has three operator()s 
    { 
     using decltype([](auto arg) { std::cout << arg << ' '; })::operator(); 
     using decltype([](double arg) { std::cout << std::fixed << arg << ' '; })::operator(); 
     using decltype([](const std::string& arg) { std::cout << std::quoted(arg) << ' '; })::operator(); 
    }; 

wyjątkiem rzeczywistym kodzie to nie będzie działać, ponieważ lambda w tym samym podmiocie nadal mają różne typy.

Tworzy typ 1 overloaded z wielokrotnym dziedziczeniem na wystąpienie.

+0

Oczywiście rozumiesz ten temat lepiej niż ja ... Czy tworzę jeden obiekt "przeciążony" z wieloma dziedziczeniami? A może 3 "przeciążone" obiekty? –

+0

@ JonathanMee Mijamy jeden obiekt, który ma trzech operatorów, którzy z kolei nazywają jedną z trzech lambd, z której czerpiecie. W końcu możesz po prostu stworzyć typ i samemu zapewnić te operatory, to jest tylko skrót na przykład. –

+0

@BartekBanachewicz To wydaje się nie być zgodne z tym, co mówi 'nwp'. Wydaje mi się, że mijam 3 pojedyncze lambdy. –