Przejdźmy krok po kroku.
auto foo() -> decltype(std::declval<T>().value, void())
Jest to końcowy typ powrotu. Można używać parametrów, ale tutaj nie jest to konieczne. Domyślam się, że napisano tak, żeby było wyraźniej. decltype
znajduje typ wyrażenia w środku, ale to wyrażenie nie jest w rzeczywistości obliczane. std::declval
służy do tworzenia instancji typu przekazanego do niej. Operator przecinka służy tutaj do generowania ogólnego zwrotu typu void
, ponieważ operator przecinka ocenia lewą stronę, odrzuca ją, ocenia prawą stronę i zwraca ją.
Pierwsza część tworzy rodzaj SFINAE (chociaż nigdy nie widziałem, żeby była używana w ten sposób). Na przykład, jeśli masz przeciążenie foo
, które zrobiło to samo z value2
zamiast , nie byłoby żadnej niejednoznaczności do wywołania. Zobacz here o co mi chodzi. Porównaj go z this one, który ma tylko typ zwrotu void
i powoduje błędy.
static_assert(T{}.value == 10, "Incorrect value");
Linia ta pilnuje instancja wartości zainicjowany z T
został członkiem jego value
mieć wartość 10. Jeśli nie, to błąd kompilatora z tego tekstu jest generowany.
} var;
To jest tylko globalny obiekt tej klasy do użycia.
struct apple
{
int value{10};
};
To jest klasa próbki do przetestowania. Ma element value
i ten element ma wartość 10 w instancji inicjowanej wartością (również inicjowana domyślnie).
var.foo<apple>();
To po prostu wywołuje funkcję.
The -> to końcowy typ powrotu. 'declval' tworzy instancję klasy. 'decltype' znajduje typ wyrażenia podczas kompilacji. 'static_assert' jest asemblowaniem podczas kompilacji. Czas połączyć je w całość :) – chris
Niejasny tytuł nie przyda się innym osobom z tym samym pytaniem. –
@RiaD: Chociaż edycja tytułu jest bardziej pomocna, wciąż jest niedokładna - wydaje się, że pyta o konkretne użycie. –