返回对临时(内置类型)的引用

时间:2015-05-31 16:34:24

标签: c++ reference return temporary

this thread可以清楚地看到,字符串文字不能用于返回const字符串&的函数。因为存在从const char *到std :: string的隐式转换,它创建了一个临时的。

但是,如果我的返回类型完全匹配并且不需要转换,为什么我会收到警告“警告:返回对临时的引用”,例如:

include <iostream>

const int& test(){
    return 2;
}

int main(){

    std::cout << test();

}

在返回值2上不需要进行隐式转换,为什么会出现警告?我认为使用test()与执行

几乎相同
 const int& example = 2;

完全有效。此外,如果我将2更改为2.2(因此它是一个双倍)程序仍然运行(具有相同的警告),尽管事实上有从double到int的转换?我不应该遇到类似于const char *如何返回到字符串引用的问题,如果有从double到int的转换吗?

2 个答案:

答案 0 :(得分:1)

仍然创建临时。 §8.5.3/(5.2.2.2)适用 1

  

否则,会创建一个临时类型“ cv1 T1”   初始化表达式中的copy-initialized(8.5)。参考资料   然后绑定到临时。

这也适用于你的第二个例子。它不适用于类类型的prvalues或标量xvalues:两者

const A& a = A();
// and
const int& i = std::move(myint);
不要介绍一个临时的。但是,这并没有改变最终结果:在任何情况下,绑定到引用的临时将在return语句结束时销毁 - 第12.2节/(5.2):

  

函数return语句(6.6.3)中返回值临时绑定的生命周期未扩展;暂时的   在return中的完整表达结束时被销毁   言。

也就是说,临时在函数退出之前被销毁,因此你的程序会导致未定义的行为。

1 我可以继续引用整个列表来说明它的原因,但这可能会浪费答案空间。

答案 1 :(得分:0)

  

从const char *到std :: string的隐式转换,它创建了一个临时的

您正在混淆这两个主题。隐式转换并不是唯一可以创造临时转换的东西:

const std::string& test() {
    return std::string("no implicit conversions here.");
}

没有隐式转换来创建string,但创建的string仍然是临时的,因此您仍然会返回对临时对象的引用。

在您的示例中,2仍然是临时值,临时存储在堆栈的某个位置,并返回其位置/地址,以便调用者可以获取该值,但不应该这样。