2012-09-11 16 views
8

Dado el siguiente código, ¿tiene Foo el constructor de copia? ¿Es seguro usar Foo con contenedores STL?template copy constructor

class Foo 
{ 
public: 
    Foo() {} 

    template <typename T> 
    Foo(const T&) {} 
}; 

Respuesta

10

La norma dice explícitamente que un constructor de copia es un constructor no moldeado que tiene una referencia a un objeto, posiblemente, const volátil del mismo tipo. En el código anterior tiene una conversión pero no copia constructor (es decir, que se utiliza para todo, pero copias, donde se utilizará el constructor declarado implícitamente).

¿Tiene Foo un constructor de copia?

Sí, el constructor de copia declarado/definido implícitamente.

¿Es seguro utilizar Foo con los envases de la biblioteca estándar?

Con la actual definición de Foo lo es, pero en el caso general, depende de lo que los miembros Foo tiene y si el constructor de copia definido implícitamente gestiona los correctamente.

+0

¿Qué sucede si esto se declara antes de la plantilla 'Foo (const Foo &) = delete;'? ¿La clase ahora no tiene constructor de copia o se llama a la plantilla en su lugar? – orlp

+1

Si se elimina el constructor de copia, la clase no tiene uno. ;-) –

+0

@nightcracker entonces no hay un constructor de copia y el compilador da un error (a menos que tenga una expresión donde podría haberse usado el constructor de copia de movimiento). La clave es que el constructor de copia es * sin plantilla *. – juanchopanza

1

Foo tiene un constructor de copia generado por el compilador, que no puede ser reemplazado por el constructor de conversión de plantilla que ha proporcionado.

Foo f0; 
Foo f1(f0); // calls compiler-synthesized copy constructor 
Foo f2(42); // calls template conversion constructor with T=int 
+0

Parece que esto no llama al constructor de copia. : //stackoverflow.com/questions/11037644/how-do-i-get-the-copy-constructor-called-over-a-variadic-constructor –

4

De acuerdo con el Standard, un constructor de copia debe ser una de las siguientes firmas:

Foo(Foo &); 
Foo(Foo const &); 
Foo(Foo volatile &); 
Foo(Foo const volatile &); 

Foo(Foo&, int = 0,); 
Foo(Foo&, int = 0, float = 1.0); //i.e the rest (after first) of the 
           //parameter(s) must have default values! 

Desde el constructor plantilla en el código no coincide con la forma de cualquiera de los anteriores , que es nocopia -constructor.

+1

Y puede tener los parámetros predeterminados también – FrozenHeart

+0

@NikitaTrophimov: Sí, eso también. – Nawaz