Явный конструктор перемещения?
Ключевое слово explicit
рекомендуется для большинства конструкторов all, которые можно вызвать с помощью одного аргумента, за исключением конструкторов копирования.
Для конструкторов копирования он имеет возможность использовать (запретить неявное копирование через вызов функции, возврат и т.д.), но это не то, что обычно требуется.
Как насчет переместить конструкторы? Есть ли разумный случай использования, чтобы сделать их явными? Какая здесь хорошая практика?
Ответы
Ответ 1
Конструкторы перемещения explicit
могут влиять на совместимость, например. Стандартные алгоритмы. Например, std::swap<T>
требует, чтобы T
был MoveConstructible. В свою очередь, MoveConstructible задается в терминах выражения, а именно T u = rv;
(где rv
является значением r типа 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
Ответ 2
Вероятно, вам нужен неявный механизм перемещения для большинства применений. Обычно они относятся к тем же категориям, что и конструкторы копирования. Явный не рекомендуется для всех конструкторов с одним аргументом, но рекомендуется для большинства. Перемещение конструкторов в этом списке отсутствует.
Ответ 3
Ключевое слово explicit
рекомендуется для конструкторов преобразования (одиночных аргументов), чтобы избежать неожиданных преобразований в неожиданных местах.
Конструкторы копирования и конструкторы перемещения вряд ли "удивляют" в этом смысле. Они происходят в основном там, где это ожидалось. Если вы не хотите их, я бы ожидал, что они будут помечены как =delete
, а не явно.
Ответ 4
Фактический вопрос заключается в том, как можно использовать явный конструктор перемещения? Он не сможет быть вызван на rvalues, поэтому компилятор должен всегда выбирать конструктор копирования, если он доступен, или не скомпилировать.
Изменить: вот ссылка: http://www.ideone.com/nm7KM
Ответ 5
При возврате по значению из функции конструктор неявного перемещения обычно может сделать процесс более эффективным.