2015-06-18 14 views
5

Czytałem następujące pytania związane z:Dlaczego std :: result_of <int(int)> :: type valid?

  1. std::result_of simple function
  2. decltype, result_of, or typeof?

i the page on std::result_of at cppreference.com.

Wszystkie z nich wydają się wskazywać, że powinienem być w stanie używać:

std::result_of<int(int)>::type v1 = 10; 

Jednak gdy próbowałem budowania następujący program za pomocą g ++ 4.9.2

#include <type_traits> 

int foo() 
{ 
    return 0; 
} 

int main() 
{ 
    std::result_of<int(int)>::type v1 = 10;   // LINE A 
    std::result_of<decltype(foo)>::type v2 = 20;  // LINE B 
    return 0; 
} 

dostaję komunikaty o błędach dla "LINII A" i "LINII B". Komunikaty o błędach są:

socc.cc: In function ‘int main()’: 
socc.cc:10:5: error: ‘type’ is not a member of ‘std::result_of<int(int)>’ 
    std::result_of<int(int)>::type v1 = 10; 
    ^
socc.cc:11:5: error: ‘type’ is not a member of ‘std::result_of<int()>’ 
    std::result_of<decltype(foo)>::type v2 = 20; 
    ^

Komenda kiedyś skompilować:

g++ -std=c++11 -Wall socc.cc -o socc 

FWIW korzystając

typename std::result_of<int(int)>::type v1 = 10; 
typename std::result_of<decltype(foo)>::type v2 = 20; 

nie zrobić różnicę.

Wygląda na to, że nie rozumiem, jak należy używać result_of.

Czy możesz wyjaśnić, dlaczego dostaję błędy kompilatora?

+1

Masz na myśli 'result_of <(int (int)) (int)>'? –

+0

Zwróć uwagę, że 'result_of' zmieniono z C++ 11 na C++ 14, czy możesz potwierdzić, że pytasz o wersję C++ 11? –

+0

@KerrekSB, Nie, miałem na myśli 'result_of <(int(int))>'. To może być brakująca część mojego zrozumienia "wyniku". Czy mógłbyś to rozwinąć? –

Odpowiedz

10

Zgodnie z linkiem, który już napisałeś, pierwsza część argumentu do result_of musi być typem wywoływanym lub referencją do funkcji.

Załóżmy, że masz

struct Callable 
{ 
    int operator()(double); 
    void operator()(int); 
}; 

następnie result_of pomaga ustalania typ zwracany, jeśli wiesz, rodzaj argumentów. Dla powyższego przykładu:

result_of<Callable(int)>::type == void ... per definition 
result_of<Callable(double)>::type == int ... per definition 
result_of<Callable(char)>::type == void ... the int-overload matches better 
result_of<Callable(float)>::type == int ... the double-overload matches better 

W celu znalezienia typu zwracaną przez funkcję foo trzeba by przejść poprzez odniesienie funkcji:

result_of<decltype(foo)&()>::type == int 

Ale to wydaje się nieco skręcone jak mogłeś bezpośrednio napisz

decltype(foo()) == int 
12

Wydaje się, że zakładasz, że std::result_of<R(Args...)>::type jest po prostu R - to jest typ wyniku funkcji o sygnaturze R(Args...). Ale std::result_of<F(Args...)>::type jest wynikiem wywołania instancji typu F z argumentami typu Args....

Tak więc, std::result_of<int(int)>::type nie ma sensu - int obiektów nie można wywoływać.

Proszę przeczytać cppreference ponownie :)

2

Aby korzystać result_of, rodzaj zasilania musi być typu funkcja gdzie typ zwracany jest typ Callable i listy parametrów zawiera typy argumentów to nazwać z. Dlatego result_of<int(int)> pyta "jaki typ otrzymam, gdy zadzwonię pod declval<int>() z argumentem declval<int>()". Odpowiedź brzmi: nie ma typu, ponieważ int nie jest typem funkcji.

Poniżej znajduje się fragment tabeli 57:

Jeśli wyrażenie INVOKE(declval<Fn>(), declval<ArgTypes>()...) dobrze uformowane po traktowaniu, jako unevaluated operandu (punkt 5), typu element typedef wyznacza typ decltype(INVOKE (declval<Fn>(), declval<ArgTypes>()...)); inaczej, nie powinny znajdować członek type

Biorąc pod uwagę funkcję foo, można użyć:

std::result_of_t<decltype((foo))()> v1 = 10; 
std::result_of_t<decltype(&foo)()> v2 = 10; 
+0

To zaczyna mieć sens :) Biorąc pod uwagę 'foo' w moim pytaniu dlaczego nie' result_of :: type' work? –

+0

@RSahu Ponieważ to deklaruje funkcję zwracającą funkcję, której nie możesz zrobić. Zamiast tego możesz użyć 'decltype (foo) &()' lub 'decltype (foo) *()'. – 0x499602D2

+0

Żaden nie zadziałał. Zobacz http://ideone.com/lMfDOa. –

Powiązane problemy