关于将const引用绑定到临时对象的子对象

6502

用像这样的代码

#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)将输入in之前破坏该P2d临时实例,但是无论如何该值都将保留(即,不是绑定到该临时实例的实际成员,而是将创建另一个临时实例来复制该成员的值)。printfmainxP2d double

clang++(IMO正确)的临时的寿命,而不是延伸P2d实例的寿命x基准和析构函数将因此被称为printfmain

如果您创建一个类(例如),而不是使用普通double类型作为xy成员,Double则两个编译器都同意,并且它们将临时P2d对象的生存期延长printf

这是一个错误g++还是标准所允许的?

哥伦布

这由CWG 1651涵盖

问题6161213的解决(使成员访问或下标表达式应用于prvalue的结果成为xvalue)意味着将引用绑定到此类临时对象的子对象不会延长临时对象的寿命。12.2 [class.temporary]应该进行修改以确保确实如此。

现状是,仅将prvalues视为引用临时对象-因此[class.temporary] / 5“第二个上下文是将引用绑定到临时对象时的情况。”)不适用。但是,Clang和GCC尚未实际实现问题616的解决方案。center().x被视为prvalue我最好的猜测:

  • GCC根本没有对任何灾难响应做出任何反应。使用时不延伸寿命标量子对象,因为这些是被覆盖的[dcl.init.ref] /(5.2.1.1)因此,完整的临时对象不需要继续存在(请参见aschelper的答案),并且也不需要,因为引用不会直接绑定。如果子对象是类或数组类型,则引用将直接绑定,并且GCC会延长临时对象的生存期。DR 60297中已注意到这一点

  • Clang识别成员访问权限,并已经实施了“新的”生存期扩展规则-甚至可以处理演员表从技术上讲,这与其处理价值类别的方式不一致。但是,这更明智,并且一旦解决了上述灾难恢复,它将是正确的行为。

因此,我要说的是,GCC按目前的措词是正确的,但目前的措词是有缺陷且含糊不清的,Clang已对DR 1651(即N3918)实施了待决的决议本文非常清楚地涵盖了该示例:

如果E1是一个临时表达式并且E2不指定位字段,则E1.E2是一个临时表达式。

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

第二种情况是引用不直接绑定(8.5.3 dcl.init.ref)或使用临时表达式初始化时(第5节)。相应的临时对象(如果有的话)在引用的生存期内一直存在,但以下情况除外:[...不适用的异常...]

Voilà,我们的寿命延长。请注意,“相应的临时对象”不够清晰,这是提案被推迟的原因之一;修订后肯定会采用它。


是xvalue(但不是位字段),类prvalue,数组prvalue或函数lvalue,“ cv1 T1”与“ cv2 T2”或[…]引用兼容

实际上,如果子对象具有数组类型,则GCC会充分考虑到这一点,并将延长生存期。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将父对象的事件绑定到临时子对象的方法

来自分类Dev

对指针错误的引用:非常量左值引用“ const * FooBarClass”无法绑定到临时对象

来自分类Dev

为什么非常量引用参数可以绑定到临时对象?

来自分类Dev

为什么临时对象可以绑定到 const 引用?

来自分类Dev

const引用临时对象的成员

来自分类Dev

const引用临时对象的成员

来自分类Dev

const-reference绑定到临时

来自分类Dev

返回const引用vs临时对象

来自分类Dev

引用const临时对象的意外行为

来自分类Dev

使用const引用延长临时对象的寿命

来自分类Dev

绑定到参数和返回值const引用的C ++临时对象

来自分类Dev

如何使子进程对象将输出保存到临时文件,然后从临时文件中获取值?

来自分类Dev

将父类的const引用转换为派生的子对象

来自分类Dev

从r值参考移到临时子对象可以吗?

来自分类Dev

通过将它绑定到本地const引用,可以在?:表达式中创建C ++临时对象吗?

来自分类Dev

返回对临时对象的引用

来自分类Dev

有关const引用和临时对象的问题

来自分类Dev

关于移动const对象

来自分类Dev

关于对象引用的困惑

来自分类Dev

构造 const 对象与对 const 对象的引用

来自分类Dev

为什么不允许将右值引用绑定到非const引用,但是却可以在一个对象上调用非const成员函数

来自分类Dev

将临时作为const T&传递并绑定到类引用的副作用

来自分类Dev

来自 const char* 类型的临时对象的 cost char*& 类型的非常量引用的无效初始化

来自分类Dev

Javascript对象子引用

来自分类Dev

如何通过引用将功能绑定到对象?

来自分类Dev

绑定对象并进行临时编辑

来自分类Dev

C ++将Const对象引用传递给构造函数

来自分类Dev

const引用临时引用

来自分类Dev

更多右值引用和临时对象

Related 相关文章

  1. 1

    将父对象的事件绑定到临时子对象的方法

  2. 2

    对指针错误的引用:非常量左值引用“ const * FooBarClass”无法绑定到临时对象

  3. 3

    为什么非常量引用参数可以绑定到临时对象?

  4. 4

    为什么临时对象可以绑定到 const 引用?

  5. 5

    const引用临时对象的成员

  6. 6

    const引用临时对象的成员

  7. 7

    const-reference绑定到临时

  8. 8

    返回const引用vs临时对象

  9. 9

    引用const临时对象的意外行为

  10. 10

    使用const引用延长临时对象的寿命

  11. 11

    绑定到参数和返回值const引用的C ++临时对象

  12. 12

    如何使子进程对象将输出保存到临时文件,然后从临时文件中获取值?

  13. 13

    将父类的const引用转换为派生的子对象

  14. 14

    从r值参考移到临时子对象可以吗?

  15. 15

    通过将它绑定到本地const引用,可以在?:表达式中创建C ++临时对象吗?

  16. 16

    返回对临时对象的引用

  17. 17

    有关const引用和临时对象的问题

  18. 18

    关于移动const对象

  19. 19

    关于对象引用的困惑

  20. 20

    构造 const 对象与对 const 对象的引用

  21. 21

    为什么不允许将右值引用绑定到非const引用,但是却可以在一个对象上调用非const成员函数

  22. 22

    将临时作为const T&传递并绑定到类引用的副作用

  23. 23

    来自 const char* 类型的临时对象的 cost char*& 类型的非常量引用的无效初始化

  24. 24

    Javascript对象子引用

  25. 25

    如何通过引用将功能绑定到对象?

  26. 26

    绑定对象并进行临时编辑

  27. 27

    C ++将Const对象引用传递给构造函数

  28. 28

    const引用临时引用

  29. 29

    更多右值引用和临时对象

热门标签

归档