c++ - Use std::result_of_t correctly -
i'm having strange problem can't wrap head around. code:
struct foo { int operator()() const & { return 0; } double operator()() const && { return 0; } }; template<typename f> void test(f&& f) { static_assert<is_same<f&&, decltype(f)>::value, "!"); // (1) // intentionally not forwarding f using t1 = decltype(f()); using t2 = result_of_t<decltype(f)()>; using t3 = result_of_t<f&&()>; using t4 = result_of_t<f&()>; static_assert(is_same<t1, t2>::value, "!"); // (2) static_assert(is_same<t1, t3>::value, "!"); // (3) static_assert(is_same<t1, t4>::value, "!"); // (4) } foo f; test(f); // static_asserts passed test(foo{}); // (1) , (4) passed, (2) , (3) failed
since (1) seems decltype(f)
f&&
, guess (2) , (3) same. so, how decltype(f())
, result_of_t<decltype(f)()>
disagree? , why decltype(f())
, result_of_t<f&()>
same?
for test(foo{})
call decltype(f)
tells f
declared rvalue reference type, foo&&
, that's type declared with, doesn't tell value category (i.e. rvalue or lvalue).
within body of function f
lvalue (because has name), decltype(f())
not same result_of_t<f&&()>
consider:
foo&& f = foo{}; f();
here too, f
declared rvalue reference type, foo&&
, doesn't mean f()
invokes &&
-qualified member function. f
lvalue, invokes &
-qualified overload. invoke &&
-qualified overload need use std::move(f)()
make rvalue.
in test(f&&)
function have universal reference need use std::forward
restore value category of incoming argument. same type result_of_t<decltype(f)()>
need forward f
restore original value category, e.g.
using t1 = decltype(std::forward<f>(f)());
now have same type result_of_t<decltype(f)()>
Comments
Post a Comment