在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,并且
原始对象是types
T
派生对象,而新对象是typesT
派生对象(也就是说,它们不是基类子对象)。
通过重新使用存储,我们结束原始对象[basic.life] / 1的生命周期
types
T
的对象的生命周期在以下情况下结束:
如果
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
的结束。