Ответ 1
Похоже, что это ошибка в реализации GCC разрешения копирования. Стандарт C++ гласит следующее:
[class.copy.elision] (акцент мой)
Такое исключение операций копирования/перемещения, называемое разрешением копирования, допускается при следующих обстоятельствах (которые могут быть объединены для удаления нескольких копий):
- в выражении throw, когда операндом является имя энергонезависимого автоматического объекта (отличного от параметра функции или оператора catch) , область которого не выходит за пределы самого внутреннего охватывающего блока try (если он есть) ), операция копирования/перемещения из операнда в объект исключения может быть опущена путем создания автоматического объекта непосредственно в объект исключения
В следующих контекстах инициализации копирования вместо операции копирования может использоваться операция перемещения:
- если операнд-выражения-броска - это имя энергонезависимого автоматического объекта (отличного от параметра функции или оператора catch) , область которого не выходит за пределы самого внутреннего включающего блока try (если он есть),
Это семейство оптимизаций, которое позволяет избежать инициализации копирования объекта исключения или сделать его максимально эффективно. Теперь общая реализация конструкции перемещения std::string
- оставить исходную строку пустой. Похоже, это именно то, что происходит с вашим кодом. temp
во внешней области видимости перемещается из (и остается пустым).
Но это не намеченное поведение. Объем создаваемого вами temp
интервала превышает (на сегодняшний день) блок try, в который он был добавлен. Таким образом, GCC не имеет права применять к нему разрешение на копирование.
Возможный обходной путь заключается в размещении декларации temp
внутри в while
цикла. Это инициализирует новый объект std::string
каждой итерации, поэтому даже если GCC
удаляется от него, это не будет заметно.
Еще один обходной путь был упомянут в комментариях и заключается в том, чтобы сделать внешний temp
объект постоянным объектом. Это приведет к принудительному копированию (поскольку операция перемещения требует неконстантного исходного объекта).