我有这个奇怪的问题,我无法绕过头脑。对于此代码:
foreach($parameter as $value) {
print_r($value['name']);
$m = 0;
foreach($question as $description) {
print_r($m . ". " . $description);
$m++;
}
}
由于(1)似乎说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
是decltype(f)
,我猜(2)和(3)实际上是相同的。那么,F&&
和decltype(f())
怎么能不同意?为什么result_of_t<decltype(f)()>
和decltype(f())
相同?
答案 0 :(得分:8)
对于test(Foo{})
来电,decltype(f)
告诉您f
被声明为右值引用类型Foo&&
,但这是与其声明的类型,它并没有告诉你它的价值类别是什么(即价值或左值)。
在函数f
的正文中是左值(因为它有一个名称),因此decltype(f())
与result_of_t<F&&()>
考虑:
Foo&& f = Foo{};
f();
此处,f
被声明为右值引用类型Foo&&
,但这并不意味着f()
调用&&
- 限定成员函数。 f
是左值,因此它调用&
- 限定的重载。要调用&&
- 限定的重载,您需要使用std::move(f)()
使其成为右值。
在具有通用引用的test(F&&)
函数中,您需要使用std::forward
来恢复传入参数的值类别。要获得与result_of_t<decltype(f)()>
相同的类型,您需要转发f
以恢复其原始值类别,例如
using T1 = decltype(std::forward<F>(f)());
现在它的类型与result_of_t<decltype(f)()>