【问题标题】:Returning reference to temporary (built in types)返回对临时的引用(内置类型)
【发布时间】:2015-05-31 16:34:23
【问题描述】:

this thread 可以清楚地看出,字符串文字不能用于返回 const string& 的函数,因为从 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(所以它是双精度),尽管事实上存在从双精度到 int 的转换,但程序仍然运行(带有相同的警告)?如果有从 double 到 int 的转换,我不应该遇到类似于如何将 const char* 返回到字符串引用的问题吗?

【问题讨论】:

  • 引用不能直接绑定到右值。相反,构造了一个int 类型的临时对象(在test 内部)并初始化为2,并返回对该对象的引用。临时对象在那一刻被销毁,使引用悬空。
  • @Igor Tandetnik 我明白了,谢谢。对我来说,我链接的线程看起来像是一个只有在发生隐式转换时才会遇到的问题。
  • 以及它“有效”的“事实”,嗯,这只是 UB。
  • 欺骗stackoverflow.com/q/6896334/560648 虽然答案不是很好;你需要一个标准的报价,真的。
  • @LightnessRacesinOrbit 如果这里的答案质量更高,我们可能会关闭您链接的问题作为这个问题的欺骗?

标签: c++ reference return temporary


【解决方案1】:

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

否则,会创建一个临时类型“cv1T1”并 从初始化表达式复制初始化(8.5)。参考资料 然后绑定到临时。

这也适用于您的第二个示例。它不适用于类类型的纯右值或标量 xvalues:两者

const A& a = A();
// and
const int& i = std::move(myint);

不要引入临时的。但是,这不会改变最终结果:无论如何,绑定到引用的临时文件将在 return 语句的末尾被销毁 - §12.2/(5.2):

临时绑定到函数return 语句(6.6.3)中返回值的生命周期没有延长;暂时的 在return 中的完整表达式的末尾被销毁 声明。

也就是说,临时对象在函数退出之前就被销毁了,因此您的程序会引发未定义的行为。


1我可以继续引用整个列表来说明为什么会这样,但这可能会浪费答案空间。

【讨论】:

    【解决方案2】:

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

    您将这两个主题混为一谈。隐式转换并不是唯一可以创建临时变量的东西:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-11-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多