使用C ++ 0x decltype返回值时返回局部变量的地址或临时值

时间:2010-07-01 14:58:19

标签: visual-studio-2010 c++11 type-inference

修改

这确实是编译器中的一个错误,我打开了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中的错误还是我错过了什么。

1 个答案:

答案 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>