lvalue / rvalue参数的std :: result_of

时间:2016-06-15 18:34:34

标签: c++ c++11

我在玩游戏时注意到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更喜欢为第三种情况采用右值参考的函数?

2 个答案:

答案 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会告诉您的内容。