Это связано с [expr.unary.op] / 1
Унарный оператор *
выполняет косвенное обращение: выражение, к которому он применяется, должно быть указатель на тип объекта или указатель на тип функции и результатом является lvalue , ссылающееся на объект или функцию, на которые указывает выражение. Если тип выражения «указатель на T
», тип результата будет «T
». [Примечание: допустимо перенаправление через указатель на неполный тип (кроме cv void). Полученное таким образом l-значение может использоваться ограниченным образом (например, для инициализации ссылки); это lvalue не должно быть преобразовано в prvalue, см. [conv.lval]. - Конечная нота]
выделенная мина
Поэтому при разыменовании this
вы получите lvalue. Неважно, указывает ли это на временный объект или нет, вы всегда получите lvalue. Поскольку *this
является lvalue, вам по закону разрешено возвращать ссылку lvalue, программа в синтаксически правильная. Семантически это не так, но это гораздо сложнее проверить, и часто это не то, что диагностируется, так как для этого требуется немало анализа c.
Было бы здорово, если бы язык мог быть обновлен, если *
возвращает значение lvalue только при применении к this
в функции, не соответствующей rvalue.