Семантика перемещения в C++ предназначена для эффективного переноса ресурсов из временных объектов. Если оператор перемещения (например, operator= или конструктор перемещения) не помечен как noexcept, компилятор не может безопасно использовать его при автоматическом выборе между копированием и перемещением в некоторых стандартных алгоритмах и контейнерах (например, при изменении размера std::vector).
Причина в следующем:
Когда оператор перемещения помечен как noexcept, компилятор знает, что исключение из него не будет сгенерировано. Это позволяет стандартным алгоритмам и контейнерам безопасно использовать перемещение, полагаясь на то, что операция завершится успешно и не нарушит целостность данных в случае, если потребуется откатиться.
Без noexcept, даже если операция перемещения в реальности не генерирует исключений, компилятор не может гарантировать этого и вынужден выбрать копирование (которое обычно предоставляет более сильные гарантии исключений), чтобы обеспечить целостность контейнера в случае потенциального исключения.
Пример:
c
В main, при vec1.resize(3), элементы будут скопированы, потому что Resource не гарантирует, что перемещение не бросит исключения. При vec2.resize(3), элементы будут перемещены, потому что ResourceNoexcept помечен как noexcept, что позволяет вектору безопасно использовать семантику перемещения при переаллокации.