2013-09-06 2 views
40

Кажется, что вектор будет проверять, если конструктор перемещения помечен как noexcept, прежде чем принимать решение о перемещении или копировании элементов при перераспределении. Является ли конструктор перемещения по умолчанию как noexcept? Я видел следующую документацию, но она не указала это. http://en.cppreference.com/w/cpp/language/move_constructorЯвляется ли конструктором Move по умолчанию как noexcept?

Косвенно объявленная движение Конструктор

Если ни один пользователь определенные перемещать конструкторы предусмотрены для типа класса (структура, класс, или союз), и все из следующих условий: есть нет объявленной пользователем копии конструкторов нет пользовательских операторов присваивания копий нет операторов, объявленных пользователем операторов присваивания, нет объявленных пользователем деструкторов, неявно объявленный конструктор перемещения не определен как удаленный из-за условий, подробно описанных в следующем разделе , тогда компилятор объявит конструктор перемещения как встроенный public член его класса с подписями T :: T (T & &) Класс может содержать многострочных конструкторов, например. как T :: T (const T & &), так и T :: T (T & &). Если имеются определенные пользовательские конструкторы перемещения, пользователь может все еще принудительно генерировать неявно объявленный конструктор перемещения с ключевым словом по умолчанию.

ответ

48

Я думаю, что ответ 15.4/14 (спецификации исключений):

Наследующего конструктор (12,9) и неявно объявляется специальная функция-члена (раздел 12), имеет исключение спецификации. Если f является наследуя конструктор или неявно объявлен конструктор по умолчанию, конструктор копирования, перемещение конструктор, деструктор, копирующий оператор присваивания, или переместить оператор присваивания, его неявное исключений спецификация определяет тип идентификатор T тогда и только тогда, когда T допускается по значению функции, непосредственно вызываемой неявным определением f; f разрешает все исключения, если какая-либо функция, которую он вызывает напрямую, допускает все исключения, а f имеет спецификацию исключения noexcept(true), если каждая функция, которую он вызывает напрямую, не позволяет исключений.

В принципе, это делает то, что вы думаете, и конструктор с неявным объявлением - это noexcept всякий раз, когда это может быть.

+29

Дополнительная информация: И вы можете проверить, были ли выполнены ваши ожидания: 'static_assert (std :: is_nothrow_move_constructible :: значение,« MyType должно быть небезопасным MoveConstructible »);' –

+0

Итак, все функции, вызываемые неявным специальным функции-члены должны быть объявлены 'noexcept' для неявных специальных функций-членов как' noexcept'. Значит, вы должны быть достаточно усердны, чтобы отметить все соответствующие функции 'noexcept', значит, есть много места для человеческой ошибки, не так ли? – mucaho

+1

@mucaho: Ну, если все ваши члены сами используют неявно определенные специальные элементы, то это не так сложно. Простым правилом является правило единой ответственности, и по умолчанию единственная человеческая ошибка, которую вы должны соблюдать, - это определение специальных функций-членов явно.Это оставляет только классы специального назначения (такие как 'unique_ptr'), которые вам нужно проверять. –

Смежные вопросы