gpt4 book ai didi

c++ - 关于将 const 引用绑定(bind)到临时对象的子对象

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:46:03 46 4
gpt4 key购买 nike

代码如下

#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;
printf("x = %.18g\n", x);
return 0;
}

g++(版本 5.2.0)将在 中输入 printf 之前销毁 P2d 临时实例 main,但该值无论如何都会被保留(即,不是将 x 绑定(bind)到临时 P2d 实例的实际成员,而是创建 另一个临时的 double 来复制成员的值)。

clang++(IMO 正确)改为将临时 P2d 实例的生命周期延长到 x 引用的生命周期,析构函数将是因此在 main 中调用 after printf

如果不是使用普通 double 作为 xy 成员的类型,而是创建一个类(例如 Double) 然后两个编译器都同意,他们将临时 P2d 对象的生命周期延长到 printf 之后。

这是 g++ 中的错误还是标准允许的错误?

最佳答案

CWG 1651 涵盖了这一点:

The resolution of issues 616 and 1213, making the result of a member access or subscript expression applied to a prvalue an xvalue, means that binding a reference to such a subobject of a temporary does not extend the temporary's lifetime. 12.2 [class.temporary] should be revised to ensure that it does.

现状是only prvalues are treated as referring to temporaries - 因此 [class.temporary]/5 (“第二个上下文是当引用绑定(bind)到临时对象时。”)不被认为是适用的。不过,Clang 和 GCC 并未实际执行问题 616 的决议。 center().x is treated as a prvalue by both .我的最佳猜测:

  • GCC 根本没有对任何 DR 使用react。使用标量子对象 时不会延长生命周期,因为[dcl.init.ref]/(5.2.1.1)涵盖这些对象。所以完整的临时对象不需要继续存在(参见 aschelper's answer ),它不需要,因为引用不直接绑定(bind)。如果子对象是类或数组类型,则引用直接绑定(bind),GCC 会延长临时对象的生命周期。这已在 DR 60297 中注明。 .

  • Clang 识别成员访问并实现了“新的”生命周期延长规则 - 它甚至 handles casts .从技术上讲,这与其处理值(value)类别的方式不一致。但是,一旦上述 DR 得到解决,这将更加明智并且是正确的行为。

因此我会说 GCC 目前的措辞是正确的,但目前的措辞有缺陷且含糊不清,Clang 已经实现了 DR 1651 的未决决议,即 N3918 .本文非常清楚地涵盖了示例:

If E1 is a temporary expression and E2 does not designate a bit-field, then E1.E2 is a temporary expression.

center() 是根据论文对 [expr.call]/11 的措辞的临时表达式。因此,其在上述 [class.temporary]/5 中的修改后的措辞适用:

The second context is when a reference does not bind directly (8.5.3 dcl.init.ref) or is initialized with a temporary expression (clause 5). The corresponding temporary object (if any) persists for the lifetime of the reference except: [...inapplicable exceptions...]

瞧,我们有生命周期延长。注意“对应的临时对象”不够明确,是提案延期的原因之一;一旦修改,一定会被采纳。


is an xvalue (but not a bit-field), class prvalue, array prvalue or function lvalue and “cv1 T1” is reference-compatible with “cv2 T2”, or […]

事实上,GCC 完全尊重这一点,如果子对象具有数组类型,它将延长生命周期。

关于c++ - 关于将 const 引用绑定(bind)到临时对象的子对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38241594/

46 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com