2014-02-09 4 views
1

Как указал Скотт Мейерс (http://channel9.msdn.com/Events/GoingNative/2013/An-Effective-Cpp11-14-Sampler на 00.34.45), только если функции перемещения класса объявлены не метательными (предпочтительно без каких-либо исключений), и только тогда вектор :: push_back() может использовать семантику перемещения ,Исключительные гарантии и быстрый push_back

Итак, каковы спецификации исключения компилятора класса сгенерированные функции перемещения, и если не предоставляется сильная гарантия исключения, означает ли это, что я не получаю никакой оптимизации из семантики перемещения в C++ 11 push_back() и других подобных методах?

+2

Поскольку функции перемещения с помощью компилятора (дефолт) перемещаются по элементам, это зависит от членов, которые неявно заданы для обеспечения безопасности исключений, и не является ли функция незанятой или нет. Кроме того, 'vector' будет использовать семантику перемещения, когда копия ctor типа элемента не может быть вызвана (например, удалена или закрыта). – dyp

ответ

3

В спецификации исключений для неявно генерируемых ходов (а также неявных копий и унаследованных конструкторов), подробно описана в 15,4/14:

Наследующий конструктор (12.9) и неявно объявляется специальная функция-член (пункт 12) имеют спецификацию исключения . Если f является наследуя конструктор или неявно объявлен конструктор по умолчанию, конструктор копирования, перемещения конструктор, деструктор, копирующий оператор присваивания, или переместить оператор присваивания, его неявное исключений спецификация определяет типа идентификаторT тогда и только тогда, когда T разрешено с помощью спецификации исключения функции, непосредственно вызванной неявным определением f; f допускает все исключения, если какая-либо функция, которую он вызывает напрямую, допускает все исключения, а f имеет спецификацию исключения noexcept(true), если каждая функция, которую он вызывает напрямую, не позволяет исключений. [Примечание: Из этого следует, что f имеет спецификацию исключений noexcept(true), если он не вызывает никаких других функций. -end note] [Примечание: В экземпляре шаблона конструктора-наследующего объекта подразумевается спецификация исключения , как если бы это был конструктор, не содержащий шаблонов. -end note]

Whew.

Таким образом, компилятор эффективно объявляет неявные ходы для вашего класса, как возможно, бросая объединение каких-либо исключений, объявляемых каждым из мутаций. Если они все noexcept, ваш ход вашего класса - noexcept.

Вы правы, что вещи, такие как vector перераспределение, предпочитают копировать тип, когда тип скопируется и его операции перемещения могут быть выбрасываться. По этой причине очень неплохо было бы разработать конструкцию перемещения и назначение классов, которые вы планируете хранить в контейнерах, для noexcept.

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