Как интерпретировать требование достижимости std::launder?

Функция 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 неопределенным поведением в примере.

  1. Я неправильно понял здесь формулировку или она неверна?
  2. Каково предполагаемое значение, которое сделало бы пример действительным?

Ответы

Ответ 1

Просто следуя примеру, соответствующий текст (жирный шрифт мой):

Байт памяти доступен через значение указателя, которое указывает на объект Y, если он находится внутри хранилища, занятого Y

Благодаря новому размещению, значение указателя теперь указывает на "вновь размещенный" объект, и, следовательно, достижимость этого.

Я бы сказал, что достаточно ясно, как оно есть.