Что делает неправильное поведение недопустимого объекта (ссылка, указатель, что угодно) неопределенным: lvalue-to-rvalue conversion (§4.1):
Если объект, к которому относится ссылка glvalue не является объектом типа T и не является объектом типа, производного от T, или если объект не инициализирован, программа, которая требует этого преобразования, имеет неопределенное поведение.
blockquote>Предполагая, что мы 't перегружен
operator&
, унарный оператор&
принимает lvalue в качестве своего операнда, поэтому никакого преобразования не происходит. Наличие только идентификатора, как и вx;
, также не требует преобразования. Вы получите только неопределенное поведение, когда ссылка используется как операнд в выражении, ожидающем, что этот операнд будет значением rvalue, что имеет место для большинства операторов. Дело в том, что выполнение&x
фактически не требует доступа к значениюx
.Я считаю, что ваш код хорошо определен.
Когда перегрузка
operator&
была перегружена, выражение&x
преобразуется в вызов функции и не подчиняется правилам встроенных операторов - вместо этого он следует правилам вызова функции. Для функции&x
вызов функции перевода означает либоx.operator&()
, либоoperator&(x)
. В первом случае преобразование lvalue-rvalue будет происходить наx
, когда используется оператор доступа к члену класса. Во втором случае аргументoperator&
будет инициализирован с помощьюx
(как вT arg = x
), а поведение этого зависит от типа аргумента. Например, в случае, если аргумент является ссылкой lvalue, нет неопределенного поведения, поскольку преобразование lvalue-rvalue не происходит.Итак, если
operator&
перегружен для типаx
, код может быть или не быть корректным, в зависимости от вызова функцииoperator&
.Можно утверждать, что унарный оператор
&
полагается на наличие хотя бы некоторой допустимой области что у вас есть адрес:В противном случае, если тип выражения равен
blockquote>T
, результат имеет тип «указатель наT
» и является значением praleue, которое является адрес выделенного объектаИ объект определяется как область хранения. После уничтожения объекта, эта область хранения больше не существует.
Я предпочитаю полагать, что это приведет только к неопределенному поведению, если к нему действительно обращается недопустимый объект. Ссылка все еще полагает, что это относится к некоторому объекту, и он может с радостью указать адрес, даже если он не существует. Однако это, кажется, некорректная часть стандарта.
Кроме
В качестве примера неопределенного поведения рассмотрим
x + x
. Теперь мы попали в другую нечеткую часть стандарта. Категория значений операндов+
не указана. Как правило, из § 5/8 вытекает, что если он не указан, тогда он ожидает значение prvalue:Всякий раз, когда выражение glvalue появляется как операнд оператора, который ожидает prvalue для этого операнда , для преобразования выражения в prvalue применяются переменные lvalue-to-rvalue (4.1), стандартные переменные (4.2) или стандартные функции (4.3).
blockquote>Теперь, поскольку
x
является lvalue, требуется преобразование lvalue-rvalue, и мы получаем неопределенное поведение. Это имеет смысл, потому что добавление требует доступа к значениюx
, чтобы он мог выработать результат.