在C ++中“重新绑定”引用是否合法?

在C ++中是否合法?

据我所知, Reference有一个微不足道的析构函数,所以它应该是合法的。
但是我认为引用不能合法地反弹……可以吗?

 template<class T> struct Reference { T &r; Reference(T &r) : r(r) { } }; int main() { int x = 5, y = 6; Reference<int> r(x); new (&r) Reference<int>(y); } 

我想我在“引用” 下面的一段话里find了答案,那里提到的是一个小小的副作用,即[basic.life] / 7:

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

  • 新对象的存储正好覆盖原对象占用的存储位置

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

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

  • 原始对象是typesT派生对象,而新对象是typesT派生对象(也就是说,它们不是基类子对象)。

通过重新使用存储,我们结束原始对象[basic.life] / 1的生命周期

typesT的对象的生命周期在以下情况下结束:

  • 如果T是具有非平凡析构函数的类types,则析构函数调用将开始,或者

  • 对象占用的存储空间被重用或释放。

所以我认为[basic.life] / 7涵盖了这个情况

 Reference<int> r(x); new (&r) Reference<int>(y); 

在那里我们结束由r表示的对象的生命周期,并在相同的位置创build一个新的对象。

由于Reference<int>是带有引用数据成员的类types,因此[basic.life] / 7的要求满足。 也就是说, r甚至可能不会引用新的对象,我们可能不会使用它来“操纵”这个新创build的对象(我把这个“操作”也解释为只读访问)。

您不是重新绑定引用,而是在新的位置创build另一个新的对象。 由于旧对象的析构函数从来没有运行,我认为这将是未定义的行为。

在你的例子中没有参考被反弹。 第一个引用(在第二行用名字rr构造)绑定到整个生命周期的x表示的int 。 当包含对象的存储被第三行中的放置新expression式重新使用时,该引用的生存期结束。 replace对象包含一个引用,该引用在其整个生命周期中绑定y ,直到其作用域结束 – main的结束。