2017-07-10 20 views
11

starałem się zrozumieć poniższy przykład, który dostałam od http://en.cppreference.com/w/cpp/utility/variant/visitUżywanie std :: odwiedzić ze zmiennej liczbie argumentów szablonu struct

#include <iomanip> 
#include <iostream> 
#include <string> 
#include <type_traits> 
#include <variant> 
#include <vector> 


using var_t = std::variant<int, long, double, std::string>; 

template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; }; 
// what is this declaration imply??? 
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; 

int main() { 
    std::vector<var_t> vec = {10, 15l, 1.5, "hello"}; 


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

Może ktoś proszę wyjaśnić, jak to działa przeciążony struct? Szczególnie nie zrozumiałem poniższej deklaracji.

template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; 

Bez tej deklaracji kompilator wydaje następujące komunikaty o błędach.

main.cpp: In function 'int main()': 
main.cpp:26:9: error: class template argument deduction failed: 
     }, v); 
     ^
main.cpp:26: confused by earlier errors, bailing out 

Cel: nauka

+0

Istnieje [propozycja] (http://open-std.org/JTC1/SC22/WG21/docs/papers/2016/p0051r2.pdf), aby dodać coś takiego do standardowej biblioteki jako 'std :: overload' i [a 5-minutowe wideo] (https://www.youtube.com/watch?v=1gNzhE-Tn40&list=PLs3KjaCtOwSZ2tbuV1hx8Xz-rFZTan2J1&index=50) na temat implementacji tego. –

Odpowiedz

10

Może ktoś proszę wyjaśnić, jak działa ten przeładowany struct? Szczególnie nie zrozumiałem poniższej deklaracji.

template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; 

To user-defined deduction guide (Link do projektu roboczego).
Jest to funkcja języka wprowadzonego przez najnowszą wersję standardu wraz z odejściem od szablonów klas. Zobacz także here, aby uzyskać więcej szczegółowych informacji i bardziej przyjazne dla użytkownika wyjaśnienie.
To nie jest właściwe wyjaśnienie, ale dla uproszczenia można uznać to za podpowiedź, którą można podać, aby odciąć argumenty szablonu ze zbioru parametrów podanych konstruktorowi.


Na marginesie, here znalazłem przykład, że jest całkiem jasne i warto kopiując go:

template<typename T> 
struct Thingy { T t; }; 

Thingy(const char *) -> Thingy<std::string>; 

// ... 

Thingy thing{"A String"}; // thing.t is a `std::string`. 

Kredyty są dla @NicolBolas, aktywnym użytkownikiem tutaj na SO. Niestety nie mogę znaleźć odpowiedzi, z której ten przykład został podjęty.

+0

Wielkie dzięki ... –

+1

@PaulVarghese Nie ma za co. Tak działa SO: jedno otwiera pytanie, ktoś inny stara się odpowiedzieć. Mam nadzieję, że ta odpowiedź może pomóc Tobie i przyszłym czytelnikom. – skypjack

+3

Należy zauważyć, że "przeciążenie" działa, ponieważ inicjalizacja agregacji w C++ 17 została rozszerzona, aby móc zainicjować podobiekty klasy podstawowej, a także członków. Również "Nicol Bolas", [Tyrant of Worlds] (http://magic.wizards.com/en/story/planeswalkers/nicol-bolas), a nie Nicolas. –

Powiązane problemy