При гарантированном исключении копирования C ++ 17 invoker
, возвращаемое get_return_object()
, является prvalue и, следовательно, не должно материализоваться до тех пор, пока оно не будет возвращено из f()
.
Это было бы правдой, только если бы вызов функции сопрограммы гарантированно генерировал свое возвращаемое значение с помощью вызова, эквивалентного созданию группы объектов в отдельном стеке, а затем вызову get_return_object()
одного из них. То есть вопрос в том, использует ли путь от get_return_object()
до самого вызова функции только prvalues.
Давайте посмотрим на , что говорит стандарт :
Выражение promise.get_return_object()
используется для инициализации результата glvalue или объекта результата prvalue вызова сопрограммы. Вызов get_return_object
упорядочивается перед вызовом initial_suspend
и вызывается не более одного раза.
Обратите внимание, что в нем говорится, что он инициализирует «объект результата prvalue». Это тот же язык, который используется в определении поведения оператора return
:
оператор return инициализирует результат glvalue или объект результата prvalue (явного или неявный) вызов функции путем копирования-инициализации из операнда.
Единственное сомнение, которое я хотел бы сказать, что стандарт явно требует гарантированного исключения между get_return_object
и вызывающий сопрограмму является последней частью около initial_suspend
. Поскольку что-то происходит между инициализацией «объекта результата prvalue» и возвратом управления вызывающей стороне, возможно, должен быть посредник, из которого необходимо скопировать / переместить.
Но тот факт, что он использует тот же язык, что и return
, предполагает, что он должен обеспечивать точно такое же поведение .
При работе в сопрограмме MSV C реализация, ваш код (с небольшими изменениями для различий в том, где определены определенные типы) работает нормально . В сочетании с приведенными выше доказательствами я бы сказал, что это говорит о том, что это ошибка компилятора.