std::result_of for lvalue/rvalue arguments

std::result_of for lvalue/rvalue arguments

本文关键字:rvalue arguments lvalue of result std for      更新时间:2023-10-16

我在玩耍时注意到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更喜欢第三种情况的RVALUE参考的功能?

std::result_of当给定的非参数参数假定它们是rvalues时。

实际上,在几乎所有情况下,std::result_of_t<A(B)>std::result_of_t<A(B&&)>相同。

如果您想了解原因,您可以在这里看到一些可能的实现。基本上,result_of_t<A(B)>执行decltype( std::declval<A>()(std::declval<B>()) )(忽略成员函数指针案例),并且B&& RVALUE参考和临时B将调用A上任何operator()的过载。

有三个主要值类别(lvalue,prvalue和xvalue),三个参考资格符(无,&&&)。

显然,&应指定LVALUE类别,而&&应指定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告诉您的内容。