Ответ 1
Я думаю, что часть стандарта, которая описывает наиболее точное, что выполняет доступ, - [basic.life]. В этом параграфе объясняется, что можно сделать с ссылкой, которая ссылается, или указателем, указывающим на объект, который не входит в его жизненный период. Все, что разрешено делать с такими объектами, не выполняет доступ к значению объекта, поскольку такое значение не существует (иначе стандарт был бы непоследовательным).
Таким образом, мы можем принять более резкий пример, если это не поведение undefined, поэтому в вашем примере кода нет доступа к e
(в соответствии с вышеизложенным рассуждением):
struct E{
E()=default;
E(const E&){}
};
E e;
e.~E();
E f(e);
Здесь e
- объект, срок жизни которого закончился, но хранилище которого все еще выделено. Что можно сделать с такой lvalue, описано в [basic.life]/6
Аналогично, до того, как началось время жизни объекта, но после того, как хранилище, которое будет занимать объект, было выделено или, после того, как срок жизни объекта закончился и перед хранилищем, которое объект занят, повторно используется или выпущен, любое значение glvalue который относится к исходному объекту, но может использоваться только ограниченным образом. Строку или разрушение объекта см. В разделе [class.cdtor]. В противном случае такое значение glvalue относится к выделенному хранилищу ([basic.stc.dynamic.deallocation]) и , используя свойства glvalue, которые не зависят от его значения, четко определено. Программа имеет undefined поведение, если:
преобразование lvalue-to-rvalue ([conv.lval]) применяется к такому glvalue,
glvalue используется для доступа к нестатическому члену данных или вызова нестатической функции-члена объекта или
glvalue неявно преобразуется ([conv.ptr]) в ссылку на тип базового класса или
glvalue используется как операнд static_cast ([expr.static.cast]), за исключением случаев, когда преобразование в конечном итоге соответствует cv char & или cv без знака char &, или
glvalue используется как операнд dynamic_cast ([expr.dynamic.cast]) или как операнд typeid.
Ни один из приведенных выше пунктов не выполняется внутри конструктора e
copy, поэтому код примера в этом ответе четко определен, что подразумевает отсутствие доступа к значению разрушенного объекта. Таким образом, в вашем примере кода нет доступа к e
.