首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么在引用类型上使用新的放置方式会给我一个分割错误,即使是使用std::launder?

为什么在引用类型上使用新的放置方式会给我一个分割错误,即使是使用std::launder?
EN

Stack Overflow用户
提问于 2021-02-12 17:01:28
回答 2查看 153关注 0票数 2

在新的C++20标准中,副院长说

临时绑定到使用直接初始化语法(括号)初始化的聚合的引用元素中的引用,而不是列表初始化语法(大括号),直到包含初始化器的完整表达式结束为止。示例: 结构A{int& r;};A a1{7};// OK,生存期扩展为A a2(7);//格式良好的引用,但存在悬空引用。

注:我使用GCC,因为这是唯一的编译器,支持这个功能。在阅读了这篇文章,并且知道引用是多态的之后,我决定创建一个简单的类:

代码语言:javascript
复制
template <typename Base>
struct Polymorphic {
    Base&& obj;
};

因此,下面的代码可以工作:

代码语言:javascript
复制
struct Base {
    inline virtual void print() const {

        std::cout << "Base !\n";
    }
};

struct Derived: public Base {
    inline virtual void print() const {

        std::cout << "Derived !" << x << "\n";
    }

    Derived() : x(5) {}
    int x;
};

int main() {
    Polymorphic<Base> base{Base()};
    base.obj.print(); // Base !
    Polymorphic<Base> base2{Derived()};
    base2.obj.print(); // Derived 5!
}

我遇到的问题是当更改多态对象的值时(不是obj的值,而是多态对象本身的值)。由于无法重新分配r值引用,所以我尝试使用placement执行以下操作:

代码语言:javascript
复制
#include <new>
int main() {
    Polymorphic<Base> base{Base()};
    new (&base) Polymorphic<Base>{Derived()};
    std::launder(&base)-> obj.print(); // Segmentation fault... Why is that?
    
    return 0;
}

我相信我有一个分段错误,因为Polymorphic<Base>有一个引用子对象。然而,我正在使用std::launder --这不是应该让它工作吗?或者这是GCC的问题?如果std::launder不能工作,我如何告诉编译器不要缓存引用?

另外,请不要告诉我“您的代码很愚蠢”,“使用唯一的指针”.我知道正常的多态是如何工作的;我问这个问题是为了加深我对安置新的和std::launder :)的理解。)

EN

回答 2

Stack Overflow用户

发布于 2021-02-12 17:12:16

[class.temporary]/6.12声明:

临时绑定到新初始化器中的引用,直到包含新初始化器的完整表达式完成为止。

对于如何初始化引用并不挑剔;这适用于所有此类引用被初始化的方式。事实上,甚至有一个例子:

结构S{ int mi;const std::pair& mp;};S{ 1,{2,3 };S* p=新的S{ 1,{2,3 };//创建悬挂引用

安置-新是一个新的-初始化。所以它适用。和上面的一样,base包含一个悬空引用。在这一点之后,如何访问它并不重要;它引用的对象已经被销毁,所以您得到了UB。

如果某些代码的读者不清楚临时的生存期,则不应该使用临时的。只要给它起个名字,你的问题就都解决了。

票数 4
EN

Stack Overflow用户

发布于 2021-02-12 17:57:05

看看您在提供的链接中引用的项目上方的要点:

一个临时绑定到在新表达式中使用的初始化器中的引用的临时绑定,直到包含该新表达式的完整表达式结束为止,而不像初始化的对象那样长。如果初始化的对象比完整表达式的生存期更长,则其引用成员将成为一个悬空引用。

在您的崩溃示例中,您使用的是一个新表达式,因此不延长生存期。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66175996

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档