[英]Use std::result_of_t correctly
I'm having this strange problem that I can't wrap my head around. 我有这个奇怪的问题,我无法绕过头脑。 For this 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); // all static_asserts passed
test(Foo{}); // (1) and (4) passed, (2) and (3) failed
Since (1) seems to say decltype(f)
is F&&
, I guess (2) and (3) are actually the same. 由于(1)似乎说
decltype(f)
是F&&
,我猜(2)和(3)实际上是相同的。 So, how could decltype(f())
and result_of_t<decltype(f)()>
disagree? 那么,
decltype(f())
和result_of_t<decltype(f)()>
不同意? And why are decltype(f())
and result_of_t<F&()>
the same? 为什么
decltype(f())
和result_of_t<F&()>
相同?
For the test(Foo{})
call decltype(f)
tells you that f
was declared as an rvalue reference type, Foo&&
, but that's the type it was declared with, it doesn't tell you what its value category is (ie rvalue or lvalue). 对于
test(Foo{})
调用decltype(f)
告诉你f
被声明为rvalue引用类型, Foo&&
,但这是它声明的类型,它不告诉你它的值类别是什么(即rvalue)或左值)。
Within the body of the function f
is an lvalue (because it has a name), so decltype(f())
is not the same as result_of_t<F&&()>
在函数体内
f
是一个左值(因为它有一个名字),所以decltype(f())
与result_of_t<F&&()>
Consider: 考虑:
Foo&& f = Foo{};
f();
Here too, f
is declared as an rvalue reference type, Foo&&
, but that doesn't mean that f()
invokes the &&
-qualified member function. 这里也将
f
声明为右值引用类型Foo&&
,但这并不意味着f()
调用&&
-qualified成员函数。 f
is an lvalue, so it invokes the &
-qualified overload. f
是左值,因此它调用&
-qualified重载。 To invoke the &&
-qualified overload you need to use std::move(f)()
to make it an rvalue. 要调用
&&
-qualified重载,您需要使用std::move(f)()
使其成为右值。
In your test(F&&)
function where you have a universal reference you need to use std::forward
to restore the value category of the incoming argument. 在您具有通用引用的
test(F&&)
函数中,您需要使用std::forward
来恢复传入参数的值类别。 To get the same type as result_of_t<decltype(f)()>
you need to forward f
to restore its original value category, eg 要获得与
result_of_t<decltype(f)()>
相同的类型,您需要转发f
以恢复其原始值类别,例如
using T1 = decltype(std::forward<F>(f)());
Now that will have the same type as result_of_t<decltype(f)()>
现在,它将与
result_of_t<decltype(f)()>
具有相同的类型
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.