将常量引用绑定到临时子对象:一个难题
下面的 C 代码片段演示了不同编译器之间的行为差异当尝试将 const 引用绑定到临时对象的子对象时:
<code class="cpp">#include <stdio.h> struct P2d { double x, y; P2d(double x, double y) : x(x), y(y) {} ~P2d() { printf("Destructor called\n"); } }; P2d center() { return P2d(10, 10); } int main(int argc, const char *argv[]) { const double& x = center().x; // Bind a reference to temporary's x member printf("x = %.18g\n", x); // Expected: 10 return 0; }</code>
错误或预期行为?
像 g 这样的编译器会终止该对象的生命周期在 main 中输入 printf 之前的临时 P2d 实例,但双成员 x 的值仍然保留。这是通过创建另一个临时双精度值来复制值而不是绑定到原始临时的成员来实现的。
另一方面,clang 正确地延长了 P2d 临时的生命周期以匹配 x 引用的生命周期,从而允许main 中 printf 之后调用的析构函数。
这种差异提出了一个问题: g 的行为是错误还是在 C 标准下是允许的?
分析和解决方案
CWG 1651 阐明了这个问题:
将引用绑定到子对象不应延长临时对象的生命周期。
在当前标准下,标量以外的对象(例如类或数组)可以延长临时对象的生命周期。
编译器行为
结论
基于 C 标准的当前措辞,GCC 的行为在技术上是正确的,而 Clang 的实现反映了 DR 1651 中提议的更改。将来很可能会修订该标准以反映这一更改。
以上是将常量引用绑定到 C 中的临时子对象是错误还是预期行为?的详细内容。更多信息请关注PHP中文网其他相关文章!