c++ - C++ - 使用 const 引用来延长一个临时的、好的或 UB 的成员?
问题描述
考虑这样的事情:
#include <iostream>
struct C {
C(double x=0, double y=0): x(x) , y(y) {
std::cout << "C ctor " << x << " " <<y << " " << "\n";
}
double x, y;
};
struct B {
B(double x=0, double y=0): x(x), y(y) {}
double x, y;
};
struct A {
B b[12];
A() {
b[2] = B(2.5, 14);
b[4] = B(56.32,11.99);
}
};
int main() {
const B& b = A().b[4];
C c(b.x, b.y);
}
当我用 -O0 编译时,我得到了打印
C ctor 56.32 11.99
但是当我用 -O2 编译时,我得到了
C ctor 0 0
我知道我们可以使用 const 引用来延长本地临时,所以像
const A& a = A();
const B& b = a.b;
将是完全合法的。但我正在努力寻找为什么相同的机制/规则不适用于任何临时的原因
编辑以供将来参考:
我正在使用 gcc 版本 6.3.0
解决方案
您的代码应该格式正确,因为对于临时人员
(强调我的)
每当引用绑定到临时对象或其子对象时,临时对象的生命周期就会延长以匹配引用的生命周期
Given A().b[4]
,b[4]
是temproray 的子对象,b
数据成员b
是 temproray 的子对象,A()
应该延长其生命周期。
使用 -O2
在 clang10 上直播 使用 -O2 在 gcc10 上直播
顺便说一句:这似乎是一个已修复的 gcc错误。
从标准来看,[class.temporary]/6
第三个上下文是引用绑定到临时对象时。36如果绑定到引用的glvalue是通过以下之一获得的,那么引用绑定到的临时对象或作为引用绑定到的子对象的完整对象的临时对象将在引用的生命周期内持续存在下列的:
...
[ 例子:
template<typename T> using id = T; int i = 1; int&& a = id<int[3]>{1, 2, 3}[i]; // temporary array has same lifetime as a const int& b = static_cast<const int&>(0); // temporary int has same lifetime as b int&& c = cond ? id<int[3]>{1, 2, 3}[i] : static_cast<int&&>(0); // exactly one of the two temporaries is lifetime-extended
—结束示例]
推荐阅读
- python - 如何在 PyQt5 布局中更紧密地对齐两个小部件?
- xamarin - 如何在 Xamarin.Forms 的中继器中标记复选框?
- flutter - ListTile 标题使它的孩子无论如何都占据全宽
- sql - Sql 查询按问题分组,创建月平均值
- kotlin - 如何在 Kotlin 中修复“未解析的引用:int”
- java - 如何确定所有顶点与某种类型顶点的最短距离?
- javascript - 移动后获取鼠标光标的坐标
- node.js - Lambda 函数导致共享访问令牌的竞争条件 | 无服务器框架 | 节点
- selenium - 在 Selenium docker grid 4 中添加实例/并发会话不起作用
- xml - 如何在csv条目中提取xml数据