【发布时间】:2020-09-18 17:09:40
【问题描述】:
[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 in this SO answer 给出了另一个示例,使用指向有效存储但类型不同的指针:
aligned_storage<sizeof(int), alignof(int)>::type data;
new(&data) int;
int *p = std::launder(reinterpret_cast<int*>(&data));
是否还有其他用例,与允许转换两个不是transparently replaceable 的对象无关,以使用std::launder?
具体来说:
-
reinterpret_cast 从 A* 到 B*,两者都是 pointer-interconvertible,在任何情况下都可能需要使用
std::launder? (即,两个指针是否可以 pointer-interconvertible 但不能透明地替换?规范在这两个术语之间没有关联)。 -
reinterpret_cast 从void* 到 T* 是否需要使用
std::launder? - 下面的代码是否需要使用
std::launder?如果是这样,规范中的哪种情况下需要这样做?
一个带有引用成员的结构,灵感来自this discussion:
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;
}
【问题讨论】:
标签: c++ language-lawyer c++20 stdlaunder