La declaración del constructor de copia declarado implícitamente no está, de hecho, siendo suprimida. Simplemente no se llama debido a las reglas de resolución de sobrecarga.
El constructor de copias declarado implícitamente tiene el formato Foo(const Foo&)
. La parte importante de esto es que requiere una referencia constante. Su plantilla de constructor toma una referencia no constante.
a
no es const, por lo que la plantilla de constructor declarada por el usuario es preferible al constructor de copia implícitamente declarado. Para llamar al constructor de copia declarada implícitamente, puede hacer a
const:
const Foo a;
Foo b(a);
o puede utilizar static_cast
para obtener una referencia constante a a
:
reglas de resolución
Foo a;
Foo b(static_cast<const Foo&>(a));
La sobrecarga que describen este se encontrado principalmente en §13.3.3.2/3 de C++ 0x FCD. Este escenario particular, con una combinación de lvalue y rvalue referencias, es una especie de descrito por los diversos ejemplos en la página 303.
Una plantilla constructor variadic suprimirá el constructor por defecto declarado implícitamente debido a una plantilla constructor es variadic usuario -declarado y el constructor por defecto declarado implícitamente se proporciona solamente si no hay constructores declarados por el usuario (C++ 0x FCD §12.1/5):
Si no hay un constructor de la clase declarada de usuario para X
, una El constructor que no tiene parámetros se declara implícitamente como predeterminado.
Una plantilla constructor variadic no suprimir el constructor de copia implícitamente declarado porque sólo un constructor no molde puede ser un constructor de copia (C++ 0x FCD §12.8/2, 3, y 8):
un constructor no molde para la clase X
es un constructor de copia si su parámetro de primera es de tipo X&
, const X&
, volatile X&
o const volatile X&
, y, o bien no hay otros parámetros o también todos los otros parámetros tienen argumentos predeterminados.
Un constructor no molde para la clase X
es un constructor movimiento si su parámetro de primera es de tipo X&&
, const X&&
, volatile X&&
, o const volatile X&&
, y, o bien no hay otros parámetros o también todos los otros parámetros tienen argumentos predeterminados.
Si la definición de clase no declara explícitamente un constructor de copia y no hay un constructor de movimiento declarado por el usuario, un constructor de copia se declara implícitamente como predeterminado.
Acabo de ejecutar una prueba rápida en gcc45, y un constructor de plantilla regular, no variadic impide la creación de un constructor predeterminado generado por el compilador también. Mi sospecha es que las reglas cambiaron en C++ 0x. –
@Dennis: Me sorprendería _realmente_ si C++ 0x cambiara las reglas que se introducirán con C++ 0x. ':)' – sbi
@Dennis ¿Entonces la respuesta vinculada es falsa? Dice que "un constructor de plantilla o un operador de asignación no suprimirán el compilador generado". – fredoverflow