使用placement new更新引用成员? [英] Using placement new to update a reference member?

查看:177
本文介绍了使用placement new更新引用成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码在C ++中是否合法?

Is the following code legal in C++?

template<typename T>
class Foo {
public:
    Foo(T& v) : v_(v) {}

private:
    T& v_;
};

int a = 10;
Foo<int> f(a);

void Bar(int& a) {
    new (&f)Foo<int>(a);
}

引用不应被绑定两次,对吗?

References are not supposed to be bound twice, right?

推荐答案

这完全无效。

[basic.life] :

[basic.life]/1, emphasis mine:


T 类型的对象的生命周期结束于:

The lifetime of an object of type T ends when:


  • 如果 T 是具有非平凡析构函数(12.4)的类类型,析构函数

  • if T is a class type with a non-trivial destructor (12.4), the destructor call starts, or
  • the storage which the object occupies is reused or released.

展示位置重新使用存储,结束由 f 表示的对象的生命周期。

The placement new reuses the storage, ending the lifetime of the object denoted by f.

[basic.life] / 7:

[basic.life]/7:


如果在对象的生命周期结束后在重新使用或释放​​对象所占用的存储
之前,新对象是在原始对象所占用的存储位置创建的
,指向原始对象的
指针,将
引用到原始对象,或者原始对象的名称将
自动引用新对象,并且一旦
新对象的生命周期开始,就可以用来操作新对象,如果:

If, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, a new object is created at the storage location which the original object occupied, a pointer that pointed to the original object, a reference that referred to the original object, or the name of the original object will automatically refer to the new object and, once the lifetime of the new object has started, can be used to manipulate the new object, if:


  • 新对象的存储与原始对象占用的存储位置完全重叠,

  • 新对象与原始对象的类型相同(忽略顶级cv限定符),

  • 原始类型对象不是const限定的,并且如果类类型不包含类型为
    const-qualified或引用类型
    的任何非静态数据成员,并且

  • 原始对象是类型 T 的最多派生对象(1.8),而新对象是类型 T (也就是说,它们是
    而不是基类子对象)。

  • the storage for the new object exactly overlays the storage location which the original object occupied, and
  • the new object is of the same type as the original object (ignoring the top-level cv-qualifiers), and
  • the type of the original object is not const-qualified, and, if a class type, does not contain any non-static data member whose type is const-qualified or a reference type, and
  • the original object was a most derived object (1.8) of type T and the new object is a most derived object of type T (that is, they are not base class subobjects).

由于第三个要点不满足,在调用 Bar 后, f 不会引用 new 创建的对象,而是之前存在的不再活的对象,并尝试使用它会导致未定义的行为。

Since the third bullet point is not satisfied, after a call to Bar, f does not refer to the object created by the placement new, but to the no-longer-living object previously there, and attempting to use it results in undefined behavior.

另请参见 CWG1776 P0137R0

这篇关于使用placement new更新引用成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆