代码之家  ›  专栏  ›  技术社区  ›  Vittorio Romeo

在具有引用成员的对象上使用“new”结果

  •  3
  • Vittorio Romeo  · 技术社区  · 7 年前

    这个 "Using placement new to update a reference member?" 问题显示此示例(简化):

    struct Foo { int& v_; };
    
    int a, b;
    Foo f{a};
    
    new (&f) Foo{b};
    
    assert(&f.v_ == &a); // UB
    

    访问 f explained by T.C. in the linked question . 我知道 std::launder

    assert(&std::launder(&f)->v_ == &a); // OK, will fire the assert
    

    但是如何使用放置返回的指针呢 new

    auto p = new (&f) Foo{b};    
    assert(&(p->v_) == &a); // UB? OK?
    

    在本例中,我们不是通过其原始名称来引用对象,而是通过任何位置来引用对象 新的

    这是未定义的行为还是标准允许的?

    1 回复  |  直到 7 年前
        1
  •  5
  •   Barry    7 年前

    这是:

    auto p = new (&f) Foo{b};    
    assert(&(p->v_) == &a); // UB? OK?
    

    定义明确。断言将触发。 new 创建新对象,然后 p 指向那个新物体。一切都很好。我们在重复使用 f 的存储,并且有很多规则 [basic.life] 关于什么是好的,什么是不好的,关于如何使用 f f 等。不能重复使用 &f 没有 launder

    但是 是一个新事物-它只是指新对象。以及 p->v_ int& 你创建的引用 b . 那不是同一个物体 a ,因此指针比较不相等。

    推荐文章