Должны ли конструкторы перемещения быть исключениями?

Я читал несколько противоречивых статей в отношении того, разрешено ли бросать конструкторы / присваивания перемещения.

Поэтому я хотел бы спросить, могут ли конструкторы / присваивания перемещений добавляться в окончательный стандарт C++11?

1 ответ

Решение

Разрешено ли бросать конструкторам перемещения? Да. Должны ли они? Нет.

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

Так что, хотя это разрешено, это не очень хорошая идея. Если вы делаете это, переосмыслите то, что вы делаете в своих операциях перемещения.

Вот, чтобы пролить свет на это.

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

Вы можете увидеть эффекты в этом примере, где noexcept не объявлено:

http://coliru.stacked-crooked.com/a/285cd07a9a52da3b

И в этом примере, где это:

http://coliru.stacked-crooked.com/a/d043774ec4c279ec

В первом примере std::vector использует конструктор копирования уже при второй и третьей вставке с push_back. Во втором примере он выполняет ту же операцию, но с конструктором перемещения.

Другие вопросы по тегам