修改
这确实是编译器中的一个错误,我打开了defect并获得了以下响应。
Hello Motti,
感谢您提交此问题。正如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
的类型std::map<int, int>
(没有引用或指针)。
这是VS10中的错误还是我错过了什么。
答案 0 :(得分:3)
call(map);
隐式将map转换为函数指针,以生成函数:
auto call( std::map<int,int>(*f)() ) -> decltype(f())
看起来VC10不符合decltype的c ++ 0x FCD,它说:
由decltype(e)表示的类型定义如下:
如果e是未加密码的id-expression或类成员访问[snip,则不是]
否则,如果e是函数调用(5.2.2)或[snip],则decltype(e)是静态选择函数的返回类型;
否则,如果e是左值,则decltype(e)为T&amp;,其中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>
。