Функция std::launder
требует, чтобы каждый байт, который был бы доступен через результат, был доступен через аргумент. "Достижимый" определяется следующим образом:
Байт памяти доступен через значение указателя, которое указывает на объект Y, если он находится внутри памяти, занятой Y, объект, который взаимозаменяемость указателя с Y или непосредственно включающий объект массива, если Y является элементом массива.
Согласно ответу на другой вопрос, это ограничение "... означает, что вы не можете использовать launder
для получения указателя, который позволил бы вам получить доступ к большему количеству байтов, чем позволяет значение исходного указателя, под страхом неопределенное поведение. "
Это имеет смысл для примеров, приведенных Т.С. но я не понимаю, как интерпретировать это в случае, когда исходный объект был заменен новым объектом, что является первоначальной целью, рассматриваемой для std::launder
. Стандарт имеет следующий пример:
struct X { const int n; };
X *p = new X{3};
const int a = p->n;
new (p) X{5}; // p does not point to new object (6.8) because X::n is const
const int b = p->n; // undefined behavior
const int c = std::launder(p)->n; // OK
В этом случае к тому времени, когда вызывается std::launder
, объект, на который указывает оригинальный объект p
---the X
, уже прекратил свое существование с момента создания нового объекта в хранилище. он оккупировал, неявно закончил свою жизнь ([basic.life]/1.4). Следовательно, кажется, что нет никаких байтов, доступных через p
, так как p
не указывает ни на какой объект Y. Это, очевидно, не предназначенное чтение, так как это сделало бы вызов std::launder
неопределенным поведением в примере.
- Я неправильно понял здесь формулировку или она неверна?
- Каково предполагаемое значение, которое сделало бы пример действительным?