I noticed this behavior of std::result_of
when playing around:
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?
Why does std::result_of
prefer the function taking an rvalue reference for the third case?
std::result_of
when given non-reference parameters presumes they are rvalues.
In fact, std::result_of_t<A(B)>
is the same as std::result_of_t<A(B&&)>
in almost all cases.
You can see some possibile implementations here if you want to see why. Basically, result_of_t<A(B)>
does a decltype( std::declval<A>()(std::declval<B>()) )
(ignoring member function pointer cases), and a B&&
rvalue reference and a temporary B
will invoke the same overloads of any operator()
on an A
.
There are three primary value categories (lvalue, prvalue and xvalue), and three reference qualifiers (none, &
and &&
).
Clearly it makes sense that &
should designate lvalue category and &&
should designate xvalue; it follows that an omitted reference qualifier should designate prvalue.
Note that this is the same as you would get for a function with the corresponding return type:
int f(); // returns prvalue int
int& f(); // returns lvalue reference to int
int&& f(); // returns xvalue reference to int
And in your case:
const int& f();
int&& g();
int h();
decltype(Foo{}(f())) a; // int
decltype(Foo{}(g())) b; // char
decltype(Foo{}(h())) c; // char
So you can see that result_of
is just showing what decltype
would tell you.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.