В соответствии с тем, что я знаю, значение результата перегруженного оператора-> () может быть любым типом t при условии, что t является либо типом указателя, либо это класс /struct, который также раскрывает перегруженного оператора-> () . По сути, компилятор должен потенциально объединить несколько вызовов этих перегруженных операторов доступа к членам, пока не будет получено результат значения типа указателя. Что меня интересует, так это то, гарантирует ли стандарт что -либо, как именно это «цепочка» должна выглядеть с синтаксической точки зрения. Рассмотрим следующий пример: < /p>
Код: Выделить всё
struct A {
int data;
A* operator->() { return this; }
};
struct B {
A operator->() { return A(); }
};
struct C {
B operator->() { return B(); }
};
int main() {
C()->data = 1;
}
Часть особого интереса здесь-перегруженная a* a :: operator-> () , которая возвращает указатель на себя (
). Мой первый вопрос заключается в том, является ли это на самом деле законным делать с точки зрения языка. Я полагаю, что это так, поскольку он соответствует требованию перегруженного оператора-> () возврата типа указателя. Единственная проблема, которую я вижу здесь, заключается в том, что могут быть некоторые условия, при которых возвращенная a* указатель может стать свисающим. И в этом заключается второй вопрос - может ли процесс цепочки множественного оператора -> () вместе компилятором за кулисами привести к недействительным. Это может произойти, например, если выражение c ()-> data = 1; будет «развертываться» в следующую синтаксически аналогичную конструкцию:
Код: Выделить всё
A* _internal_compiler_var = ((C().operator->()).operator->()).operator->(); // temporary A is constructed and immediately destroyed after obtaining the pointer value
_internal_compiler_var->data = 1; // Oops : dangling A* pointer
Напротив, выражение c ()-> data = 1; будет действительным при условии, что компилятор «развертывает». p>
Код: Выделить всё
(((C().operator->()).operator->()).operator->())->data = 1; // OK : destruction of temporary A instance is performed after the assignment
< /code>
Итак, чтобы подвести итог, что я хотел бы знать 2 вещи: < /p>
[list]
[*] ()
Возвращение этого указателя действителен, и если это так, если есть какие -либо потенциальные проблемы, которые могут возникнуть из -за этого
[*] неявные/явные гарантии о (временном) объекте Время жизни используется в цепочке перегруженного оператора-> () (частично, если эти временные объекты разрушаются после выражения в окружении или уничтожаются где-то в середине, в то время как полученное значение указателя оценивается)
[/list]
Подробнее здесь:
https://stackoverflow.com/questions/794 ... cess-opera