Edit:
这确实是编译器的一个bug,我开了一个defect https://connect.microsoft.com/VisualStudio/feedback/details/573330/bad-code-generated-for-function-using-a-decltype-return-value?wa=wsignin1.0#details并得到以下回应。
你好莫蒂,
感谢您提交此问题。正如 stackoverflow 帖子中所述,这是我们 decltype 实现中的一个错误。不幸的是,我们无法在 Visual Studio 的下一版本中修复此错误,因为代码相对不常见,而且我们的资源特别有限。
原问题如下
我正在尝试 VS10 的 C++0x 功能,遇到了以下问题。
std::map<int, int> map()
{
return std::map<int, int>();
}
template <class F>
auto call(F f) -> decltype(f())
{
auto ret = f();
return ret;
}
void check()
{
auto m = call(map);
}
我收到以下警告:
警告 C4172:返回局部变量或临时变量的地址
但是当我改变原型时call
成为旧风格:
std::map<int, int> call(F f)
没关系,什么时候也可以call
不是模板函数(即使使用推导的返回类型)。
如果我看一下类型ret
it's std::map<int, int>
(没有引用或指针)。
这是 VS10 中的错误还是我遗漏了一些东西。
call(map);
隐式将 map 转换为函数指针,以使该函数:
auto call( std::map<int,int>(*f)() ) -> decltype(f())
看起来 VC10 不符合 decltype 的 c++0x FCD,其中表示:
decltype(e) 表示的类型定义如下:
-
如果 e 是不带括号的 id 表达式或类成员访问 [剪断,它不是]
-
否则,如果 e 是函数调用 (5.2.2) 或 [snip],则 decltype(e) 是静态选择的函数的返回类型;
-
否则,如果 e 是左值,则 decltype(e) 是 T&,其中 T 是 e 的类型;
-
否则,decltype(e) 是 e 的类型。
5.2.2 明确指出通过函数指针进行调用是“函数调用”,因此decltype(f())
应该std::map<int,int>
。相反,它将 f() 视为左值表达式,其结果std::map<int,int> &
。 ret 的类型被正确推断,但它被返回转换为引用。
当您使用函数表达式而不是函数指针表达式时,不会出现此错误,decltype(map())
正确结果为std::map<int,int>
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)