Указатель - это адрес, но для объектной модели это больше, чем адрес. Он указывает на конкретный объект по этому адресу. Несколько объектов могут существовать по определенному адресу, но это не означает, что указатели на любой из этих объектов являются одновременно указателями на другие объекты по этому адресу. Посмотрите, что [expr.unary.op] / 1 говорит об косвенности указателя:
результатом является lvalue, ссылающееся на объект или функцию, на которые указывает выражение.
Не "объекту по этому адресу"; это lvalue, относящееся к объекту , на который указывает. Очевидно, что в объектной модели C ++ несколько объектов могут существовать по одному и тому же адресу, но конкретный указатель на этот адрес не указывает на все эти объекты. Это указывает только на один из них.
[expr.unary.op] / 2 говорит: «Результатом унарного оператора & является указатель на его операнд». Следовательно, &u
указывает на u
, который имеет тип u
(Кстати, действительно ли было необходимо называть объект так же, как тип?). &u
не указывает на u.i
, u.s1
или u.s2
. Все они имеют тот же адрес, что и &u
, но сам &u
указывает только на u
.
Таким образом, теперь возникает вопрос, что такое хранилище, представленное &u
? Ну, согласно [intro.object] / 1, мы знаем, что «объект занимает область памяти». Если &u
указывает на объект u
, этот указатель должен поэтому представлять область памяти, занятую этим объектом. Не хранение любого из его подобъектов; это хранилище для этого объекта. В полном объеме.
Теперь мы доберемся до new(&u) std::string{}
. Это выражение создает объект типа std::string{}
в хранилище, представленном &u
. Это означает повторное использование хранилища объекта u
. Что в соответствии с [basic.life] / 1.4, заканчивает срок жизни u
. Который заканчивает время жизни своего подобъекта активного члена.
Итак, ответ на ваш вопрос заключается в том, что ни один из них не становится активным, потому что объект u
больше не существует.