Un explicit
constructores de movimiento pueden afectar la compatibilidad con, por ejemplo, Algoritmos estándar. Por ejemplo, std::swap<T>
requiere que T
sea MoveConstructible. A su vez, MoveConstructible se especifica en términos de una expresión, concretamente T u = rv;
(donde rv
es un valor de referencia del tipo T
).
Si no hay ni un constructor de copia no explícito ni un constructor de movimiento no explícito para un tipo dado, entonces T u = rv;
no es válido y ese tipo no se puede usar con std::swap
. (En este caso particular, sin embargo, es posible especializar std::swap
para proporcionar la funcionalidad deseada, por ejemplo, usando T u(rv);
).
En pocas palabras, un constructor de movimiento o copia explicit
desafía las expectativas y no se puede utilizar tan bien con el código genérico.
Algunas otras partes de la biblioteca estándar que puso un requisito MoveConstructible:
- la Deleter de
unique_ptr<T, D>
- envoltorios de llamadas, por ejemplo, se utiliza en
bind
(todos los tipos cariados que se transmiten se refiere)
thread
, async
, call_once
(todo se especifica en términos de envolturas llamadas)
sort
, stable_sort
, nth_element
, sort_heap
¿Cuál es la diferencia entre un "constructor de copia" y un "constructor que se puede invocar con un argumento"? Solo tuve una confusión de momentos con la respuesta de DeadMGs porque pensé que eran lo mismo. Este * es * solo la forma en que se usa, y (aparte de "explícito") no es como se declara el constructor, ¿sí? ¿O me he vuelto loco? – Steve314
@ Steve314: Un constructor de copia de argumento único es específicamente un constructor 'T ([const] [volátil] T &)'. 12.8/2. 'T (int)' es un constructor que puede invocarse con un argumento, pero no es un constructor de copia porque no "copia" una instancia de 'T'. –
@Steve Jessop - sí, por supuesto. Obviamente he muerto cerebralmente. – Steve314