Явный конструктор перемещения?

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

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

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

5 ответов

Решение

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

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

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

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

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

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

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

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