Да, использование перегруженной операторной функции - это семантически вызов функции.
[over.match.oper] / 2 в стандарте C ++ говорит, выделение мое:
Если любой из операндов [в выражении оператора] имеет тип, который является классом или перечислением, может быть объявлена пользовательская операторная функция, реализующая этот оператор, или может потребоваться пользовательское преобразование для преобразовать операнд в тип, который подходит для встроенного оператора. В этом случае разрешение перегрузки используется для определения того, какая операторская функция или встроенный оператор должны вызываться для реализации оператора. Следовательно, обозначение оператора сначала преобразуется в эквивалентное обозначение вызова функции , как показано в Таблице 12 ....
Таким образом, Стандартные правила, касающиеся времени жизни объекта, применяются точно в такими же способами. Нет также причины, по которой манипулирование компилятором закулисных вещей, таких как стек вызовов, должно быть другим.
Ваш пример хорош не потому, что в операторских функциях есть что-то особенное, а потому, что он не возвращает ссылка на локальный объект. В return out;
, out
называет параметр функции ссылочным типом, поэтому он ссылается на некоторый другой объект вне области действия функции. В этом случае out
относится к переменной print
в main
, а время жизни print
заканчивается до main
.