使用 placement new 来更改 reference_wrapper 持有的变量类型是否定义了行为?

Is it defined behavior to use placement new to change type of variable that is held by reference_wrapper?

我正在搞乱新的位置,并制作了这段代码:

#include <iostream>
#include <functional>
#include <new>

int main()
{
    char memory[sizeof(int)]; //memory to hold type
    auto ref = std::ref(*new (memory) int{5}); //allocating int in memory, and make a reference to it
    std::cout << ref << std::endl;
    new (memory) unsigned{6}; //"overwrite"
    std::cout << ref << std::endl;
}

输出是5,然后是6,但是它定义好了吗?如果是这样,我可以使用 float 作为第二种类型吗?

第二个放置 new-expression 重用了第一个放置 创建的 int 对象的存储,因此结束了它的生命周期新表达式 ([basic.life]/1.4).

因为 [basic.life]/8 isn't satisfied (due to the type difference), the pointer stored by the reference wrapper doesn't point to the new object, but continues to point to the out-of-lifetime int object. Accessing the object via an lvalue obtained from such a pointer therefore has undefined behavior per [basic.life]/7.


请注意,严格别名在这里无关紧要;该规则明确允许 accessing an object via a glvalue of "a type that is the signed or unsigned type corresponding to the dynamic type of the object".