Явный конструктор перемещения? - PullRequest
22 голосов
/ 20 июля 2011

Ключевое слово explicit рекомендуется для всех большинства конструкторов, которые можно вызывать с одним аргументом , за исключением конструкторов копирования.

Для конструкторов копирования он имеет применение (запрещать неявное копирование с помощью вызова функции, возврата и т. Д.), Но это не то, что обычно требуется.

А как насчет перемещения конструкторов ? Есть ли разумные варианты использования, чтобы сделать их явными? Какая здесь хорошая практика?

Ответы [ 5 ]

21 голосов
/ 20 июля 2011

Конструкторы перемещения explicit могут влиять на совместимость, например, с Стандартные алгоритмы. Например, std::swap<T> требует, чтобы T было MoveConstructible. В свою очередь, MoveConstructible указывается в терминах выражения, а именно T u = rv; (где rv - это значение типа T).

Если для данного типа нет ни явного конструктора копирования, ни неявного конструктора перемещения, тогда T u = rv; недопустим и этот тип нельзя использовать с std::swap. (В этом конкретном случае, однако, можно специализировать std::swap для обеспечения желаемой функциональности, например, используя T u(rv);).

Проще говоря, конструктор перемещения или копирования explicit не поддается ожиданиям и не может использоваться также с общим кодом.

Некоторые другие части стандартной библиотеки, которые предъявляют требование MoveConstructible:

  • удалитель unique_ptr<T, D>
  • обертки вызовов, используемые, например, bind (все переданные распадающиеся типы касаются)
  • thread, async, call_once (все указано в терминах упаковщиков вызовов)
  • sort, stable_sort, nth_element, sort_heap
5 голосов
/ 20 июля 2011

Ключевое слово explicit рекомендуется для (одного аргумента) преобразования конструкторов , чтобы избежать неожиданных преобразований в неожиданных местах.

Скопировать конструкторы и конструкторы перемещения вряд ли "удивительно" в этомсмысл.Они происходят в основном там, где ожидали.Если вы их не хотите, я бы ожидал, что они будут помечены =delete, а не сделаны явными.

5 голосов
/ 20 июля 2011

Вы, вероятно, хотите использовать неявный конструктор перемещения для большинства применений. Они обычно попадают в те же категории, что и конструкторы копирования. Явное не рекомендуется для всех конструкторов с одним аргументом, но рекомендуется для большинства. Конструкторы перемещения отсутствуют в этом списке.

2 голосов
/ 20 июля 2011

Вопрос в том, как можно использовать явный конструктор перемещения? Он не сможет быть вызван для значений rvalue, поэтому компилятор должен всегда выбирать конструктор копирования, если он доступен, или не компилироваться.

Редактировать: вот ссылка на пример: http://www.ideone.com/nm7KM

0 голосов
/ 30 апреля 2012

При возврате по значению из функции неявный конструктор перемещения обычно может сделать процесс более эффективным.

...