使用 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".
我正在搞乱新的位置,并制作了这段代码:
#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".