通过同一词法表达式中的常量引用临时传递给多个函数的生命周期

问题描述 投票:0回答:1

根据这个问题的答案,表达式中创建的临时对象持续整个表达式。这似乎意味着我们可以通过 const 引用多次将临时值传递到函数中并从函数中返回它,而无需获得悬空引用,只要它位于同一表达式内即可。像这样的东西:

#include <iostream>
#include <string>
using std::string;

const int& foo(const int& i) {
    std::cout << i << "\n";
    return i;
}

int main(void) {
    foo(foo(foo(foo(foo(foo(100))))));
    // every instance of foo receives valid reference?
    return 0;
}

然而,这个问题引用的标准如下:

函数调用 (5.2.2) 中对引用参数的临时绑定将持续存在,直到包含调用的完整表达式完成为止。

答案之一是“这意味着直到右大括号,即}”,暗示“完整表达式”指的是函数体,这意味着在上面的示例中,临时创建的生命周期对于文字 100 应该只持续到第一次调用

foo
结束。

问题:

  1. 上例中对

    foo
    的任何调用是否使用悬空引用?

  2. 临时100的寿命是多少?它是仅扩展到第一次调用

    foo
    的参数的生命周期,还是主函数的整个第一行?

  3. 如果我要修改

    main
    的第一行:

    const int &a = foo(100);

    临时的什么时候销毁?从

    foo
    返回之后(但在分配给
    a
    之前,或者分配给
    a
    之后(即仅在这一行之后)?

c++ reference lifetime object-reference temporary-objects
1个回答
0
投票

这意味着直到右大括号

指的是参考生命周期延长,他们所指的大括号是

main
末尾的那个。

代码中临时

100
的生命周期将持续到最后一次
foo
调用之后,因为所有调用都是同一表达式的一部分。如果将结果分配给引用,则生命周期将延长至
main
:

的末尾
int main(void) {
    const int& a = foo(foo(foo(foo(foo(foo(100))))));
    std::cout << "a valid reference: " << a << "\n";
    return 0;
}
© www.soinside.com 2019 - 2024. All rights reserved.