我有一些代码在VS2015下失败,但在GCC下工作。我很确定这个bug是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的返回发生(这似乎是破坏&amp;&amp;对象的合理位置)。
在GCC下,返回的字符串不会被推断为右值引用。正如我所期望的那样,在cout语句中使用后调用析构函数。
在Visual Studio下将返回类型指定为'string'而不是decltype(auto)可以修复它,就像在test1中返回f()时使用remove_reference_t一样。
我的期望是GCC是正确的,因为zero_params()的函数签名是字符串,而不是字符串&amp;&amp;所以如果它使用decltype(auto),我会期望不引用'冒泡'到test1的返回类型。
这是正确的评估吗?
LATE EDIT:
我发现用VS2015解决这个问题的另一种方法是在lambda中包含给test1的函数:
cout << test1(zero_params) << endl;
为:
cout << test1( [](auto&&... ps) { return zero_params(std::forward<decltype(ps)>(ps)...); } ) << endl;
答案 0 :(得分:2)
所以based on the comments我们可以得出结论:
错误是:
解决方法是: