[1]
有没有必要将p0593r6 添加到 C++20(第 6.7.2.11 节对象模型[intro.object])中std::launder
,而在 C++17 中需要相同的用例std::launder
,或者它们完全正交?
[2]
[ptr::launder]规范中的示例是:
struct X { int n; };
const X *p = new const X{3};
const int a = p->n;
new (const_cast<X*>(p)) const X{5}; // p does not point to new object ([basic.life]) because its type is const
const int b = p->n; // undefined behavior
const int c = std::launder(p)->n; // OK
@Nicol Bolas在此 SO answer中给出了另一个示例,使用指向有效存储但类型不同的指针:
aligned_storage<sizeof(int), alignof(int)>::type data;
new(&data) int;
int *p = std::launder(reinterpret_cast<int*>(&data));
是否有其他用例,与允许投射两个不可透明替换的对象无关,用于使用std::launder
?
具体来说:
- 从 A* 到 B* 的reinterpret_cast是否都是指针互转换的
std::launder
,在任何情况下都可能需要使用?(即两个指针可以指针互转换但不能透明地替换吗?规范在这两个术语之间没有关联)。 - 从void*到 T* 的reinterpret_cast是否需要使用?
std::launder
- 下面的代码是否需要使用
std::launder
?如果是这样,在规范中的哪种情况下需要这样做?
受此讨论启发的具有引用成员的结构:
struct A {
constexpr A(int &x) : ref(x) {}
int &ref;
};
int main() {
int n1 = 1, n2 = 2;
A a { n1 };
a.~A();
new (&a) A {n2};
a.ref = 3; // do we need to launder somebody here?
std::cout << a.ref << ' ' << n1 << ' ' << n2 << std::endl;
}