编辑:

这确实是编译器中的错误,我打开了defect并得到以下响应。

您好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的原型(prototype)更改为旧样式时:
std::map<int, int> call(F f)

很好,当call不是模板函数时(即使使用推导的返回类型)也可以。

如果我看看ret的类型,那就是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表达式或类成员访问权限[snip,不是]
  • 否则,如果e是函数调用(5.2.2)或[snip],则decltype(e)是静态选择的函数的返回类型;否则,返回false。
  • 否则为
  • ,如果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>

    关于visual-studio-2010 - 使用C++ 0x decltype返回值时局部变量或临时变量的返回地址,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3158999/

    10-15 18:03