我在玩游戏时注意到std::result_of
的这种行为:
struct Foo {
int operator()(const int&) const { ... }
char operator()(int&&) const { ... }
};
result_of_t<Foo(const int&)> a; // int
result_of_t<Foo(int&&)> b; // char
result_of_t<Foo(int)> c; // char -- why?
为什么std::result_of
更喜欢为第三种情况采用右值参考的函数?
答案 0 :(得分:3)
std::result_of
当给定非参考参数时,假定它们是右值。
事实上,std::result_of_t<A(B)>
几乎在所有情况下都与std::result_of_t<A(B&&)>
相同。
如果您想了解原因,可以看到一些possibile implementations here。基本上,result_of_t<A(B)>
执行decltype( std::declval<A>()(std::declval<B>()) )
(忽略成员函数指针的情况),B&&
右值引用和临时B
将调用任何{{1}的相同重载} operator()
。
答案 1 :(得分:1)
有three primary value categories(左值,右值和x值)和三个reference qualifiers(无,&
和&&
)。
显然,&
应指定左值类别,而&&
应指定xvalue;因此,省略的引用限定符应指定prvalue。
请注意,这与具有相应返回类型的函数相同:
int f(); // returns prvalue int
int& f(); // returns lvalue reference to int
int&& f(); // returns xvalue reference to int
在你的情况下:
const int& f();
int&& g();
int h();
decltype(Foo{}(f())) a; // int
decltype(Foo{}(g())) b; // char
decltype(Foo{}(h())) c; // char
因此,您可以看到result_of
只显示decltype
会告诉您的内容。