我有一段代码,在VS2015中会失败,但在GCC下可以正常工作。我相信这是Visual Studio的错误,但想要确保我的decltype(auto)理解是正确的。
#include <iostream>
using namespace std;
string zero_params()
{
return "zero_params called.";
}
template< typename F >
auto test1( F f ) -> decltype(auto)
{
return f();
}
int main() {
cout << std::is_rvalue_reference< decltype(test1(zero_params)) >::value << endl;
cout << test1(zero_params) << endl;
cout << "Done!" << endl;
return 0;
}
在 Visual Studio 下,zero_params 返回的字符串被推断为右值引用。此外,在 test1() 中调用 f 后返回值的析构函数被调用(这似乎是一个合理的 && 对象的销毁位置)。在 GCC 下,返回的字符串不会被推断为右值引用。在我期望的 cout 语句中使用后析构函数被调用。
将返回类型指定为“string”而不是 decltype(auto),可以在 Visual Studio 中解决此问题,使用 remove_reference_t 在 test1 中对 f() 的返回值进行操作也可以解决。
我的期望是,由于 zero_params() 的函数签名是 string 而不是 string&&,所以我期望非引用类型会上升到 test1 的返回类型,如果它使用了 decltype(auto)。
这个评估正确吗?
后来编辑:
我发现在 VS2015 中解决这个问题的另一种方法是将给定给 test1 的函数包装在 lambda 中:
cout << test1(zero_params) << endl;
至:
cout << test1( [](auto&&... ps) { return zero_params(std::forward<decltype(ps)>(ps)...); } ) << endl;
f()
是一个prvalue,所以decltype
应该推断出std::string
而不是std::string &&
。 - T.C.decltype(auto)
不是无用的话,这个问题在VS2015发布之前真正需要被修复... - ildjarn