const引用临时奇数

Eva*_*ran 8 c++ const reference temporary

我们都知道这样的事情在c ++中是有效的:

const T &x = T();
Run Code Online (Sandbox Code Playgroud)

而:

T &x = T();
Run Code Online (Sandbox Code Playgroud)

不是.

最近一个问题中,谈话导致了这一规则.OP发布了一些明显唤起UB的代码.但我希望它的修改版本能够工作(这是修改后的版本):

#include <iostream>
using namespace std;

class A {
public:
    A(int k) { _k = k; };
    int get() const { return _k; };
    int _k;
};

class B {
public:
    B(const A& a) : _a(a) {}
    void b() { cout << _a.get(); }
    const A& _a;
};

B* f() {
    return new B(A(10));
}

int main() {
    f()->b();
}
Run Code Online (Sandbox Code Playgroud)

这会在某些机器上打印垃圾,在其他机器上打印10个......对我来说听起来像UB :-).但后来我想,A基本上int它是一个美化它所有它初始化一个并阅读它.为什么不叫Aint,看看会发生什么:

#include <iostream>
using namespace std;

typedef int A;

class B {
public:
    B(const A& a) : _a(a) {}
    void b() { cout << _a; }
    const A& _a;
};

B* f() {
    return new B(A(10));
}

int main() {
    f()->b();
}
Run Code Online (Sandbox Code Playgroud)

10每次打印.它至少看起来像const引用规则对int版本有效,但对类版本没有效果.由于堆的使用,它们都只是简单的UB吗?我对这个int版本很幸运,因为编译通过所有consts 看到并直接打印出来了10?我错过了规则的哪个方面?

AnT*_*AnT 17

它只是表明通过"在编译器中尝试"来分析语言行为通常不会产生任何有用的结果.出于同样的原因,您的两个示例均无效.

临时的生命周期仅在您使用临时值作为const引用的直接初始化程序时才会扩展 - 只会在引用和临时之间建立"生命周期"链接.

尝试传递临时作为构造函数的参数并在构造函数中附加const引用将不会建立上述链接,也不会延长临时的生命周期.

另外,按照C++标准,如果你这样做

struct S {
  const int &r;

  S() : r(5) {
    cout << r; // OK
  }
};
Run Code Online (Sandbox Code Playgroud)

临时的生命周期只延伸到构造函数的结尾.构造函数完成后,临时死亡,意味着这一点

S s;
cout << s.r; // Invalid
Run Code Online (Sandbox Code Playgroud)

是无效的.

你的实验int只是"似乎工作",纯粹是偶然的.