std::launder
cppreference.com
<tbody>
</tbody>
<tbody class="t-dcl-rev ">
</tbody><tbody>
</tbody>
template< class T > constexpr T* launder( T* p ) noexcept; |
( C++17) ( C++20) |
|
template< class T > [[nodiscard]] constexpr T* launder( T* p ) noexcept; |
( C++20) | |
Provenance fence p. , p, , .
std::launder(p) T*, x. .
, T (, cv-) void.
std::launder , () . , std::launder .
std::launder . . , .
std::launder :
, std::launder , , escape .
int x[10];
auto p = std::launder(reinterpret_cast<int(*)[10]>(&x[0])); // OK
int x2[2][10];
auto p2 = std::launder(reinterpret_cast<int(*)[10]>(&x2[0][0]));
// : x2[1] x2[0],
//
// ; ,
struct X { int a[10]; } x3, x4[2];
auto p3 = std::launder(reinterpret_cast<int(*)[10]>(&x3.a[0])); // OK
auto p4 = std::launder(reinterpret_cast<int(*)[10]>(&x4[0].a[0]));
// : x4[1] x4[0].a
// ( x4[0]),
struct Y { int a[10]; double y; } x5;
auto p5 = std::launder(reinterpret_cast<int(*)[10]>(&x5.a[0]));
// : x5.y x5.a,
//
#include <cassert>
#include <cstddef>
#include <new>
struct Base
{
virtual int transmogrify();
};
struct Derived : Base
{
int transmogrify() override
{
new(this) Base;
return 2;
}
};
int Base::transmogrify()
{
new(this) Derived;
return 1;
}
static_assert(sizeof(Derived) == sizeof(Base));
int main()
{
// 1: ,
// , .
Base base;
int n = base.transmogrify();
// int m = base.transmogrify(); //
int m = std::launder(&base)->transmogrify(); // OK
assert(m + n == 3);
// 2: ,
// , .
struct Y { int z; };
alignas(Y) std::byte s[sizeof(Y)];
Y* q = new(&s) Y{2};
const int f = reinterpret_cast<Y*>(&s)->z; //
// :
// reinterpret_cast<Y*>(&s)
// " s"
// Y
const int g = q->z; // OK
const int h = std::launder(reinterpret_cast<Y*>(&s))->z; // OK
[](...){}(f, g, h); // [[maybe_unused]]
}
C++:
| LWG 2859 | C++17 | |
|
| LWG 3495 | C++17 | std::launder |