使用C ++ 0x decltype返回值时,局部变量或临时变量的返回地址 [英] Returning address of local variable or temporary when using C++0x decltype return value

查看:69
本文介绍了使用C ++ 0x decltype返回值时,局部变量或临时变量的返回地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这确实是编译器中的错误,我打开了

This is indeed a bug in the compiler, I've opened a defect and got the following response.

你好Motti,
感谢您提交此问题.如stackoverflow发布中所述,这是我们的decltype实现中的错误.不幸的是,由于代码相对少见,因此我们无法在Visual Studio的下一发行版中修复此错误,而且我们特别受资源限制.

Hello Motti,
Thank you for submitting this issue. As noted in the stackoverflow posting, this is a bug in our decltype implementation. Unfortunately, we cannot fix this bug in the next release of Visual Studio since the code is relatively uncommon, and we are particularly resource constrained.

随后出现的原始问题

我在玩VS10的C ++ 0x功能,遇到了以下问题.

I'm playing around with the C++0x features of VS10 and I ran into the following problem.

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:返回本地变量或临时地址

warning C4172: returning address of local variable or temporary

但是,当我将 call 的原型更改为旧样式时:

However when I change the prototype of call to be the old style:

std::map<int, int> call(F f)

没关系,如果 call 不是模板函数(即使使用推导的返回类型),也可以.

It's fine, it's also OK when call is not a template function (even when using deduced return types).

如果我查看 ret 的类型,它是 std :: map< int,int> (没有引用或指针).

If I look at the type of ret it's std::map<int, int> (no references or pointers).

这是VS10中的错误还是我错过了什么?

Is this a bug in VS10 or am I missing something.

推荐答案

call(map); 隐式将map转换为函数指针,以创建函数:

call(map); implicitly converts map to a function pointer, to make the function:

auto call( std::map<int,int>(*f)() ) -> decltype(f())

VC10似乎不符合decltype的c ++ 0x FCD,它表示:

It looks like VC10 isn't meeting the c++0x FCD for decltype, which says:

由decltype(e)表示的类型定义如下:

The type denoted by decltype(e) is defined as follows:

  • 如果e是未括号的id表达式或类成员访问权限[snip,不是]

  • if e is an unparenthesized id-expression or a class member access [snip, it isn't]

否则,如果e是函数调用(5.2.2)或[snip],则decltype(e)是静态选择的函数的返回类型;

otherwise, if e is a function call (5.2.2) or [snip], decltype(e) is the return type of the statically chosen function;

否则,如果e为左值,则decltype(e)为T& ;,其中T为e的类型;

otherwise, if e is an lvalue, decltype(e) is T&, where T is the type of e;

否则,decltype(e)是e的类型.

otherwise, decltype(e) is the type of e.

5.2.2清楚地表明,通过函数指针进行的调用是函数调用".因此 decltype(f())应该为 std :: map< int,int> .相反,它将f()视为左值表达式,结果为 std :: map< int,int>& .ret的类型可以正确推断,但是由返回值将其强制转换为引用.

5.2.2 makes it clear that calling through a function pointer is a "function call" so decltype(f()) should be std::map<int,int>. Instead, it's treating f() like an lvalue espression, with the result std::map<int,int> &. The type of ret is being inferred correctly, but it's being cast into a reference by the return.

当您使用函数表达式而不是函数指针表达式时,此错误不会出现, decltype(map())正确地导致 std :: map< int,int> .

This bug doesn't show up when you use a function expression instead of a function pointer expression, decltype(map()) correctly results in std::map<int,int>.

这篇关于使用C ++ 0x decltype返回值时,局部变量或临时变量的返回地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆