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它是一个美化它所有它初始化一个并阅读它.为什么不叫A的int,看看会发生什么:
#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只是"似乎工作",纯粹是偶然的.