2011-03-20 10 views
7

Aquí es cómo puedo permitir condicionalmente un constructor de una clase:permite condicionalmente constructor

struct Foo 
{ 

    template<class T> 
    Foo(T* ptr, boost::enable_if<is_arithmetic<T> >::type* = NULL) 
    {} 

}; 

me gustaría saber por qué tengo que hacer la habilitación a través de un parámetro ficticio. ¿Por qué no puedo simplemente escribir:

struct Foo 
{ 
    template<class T> 
    Foo(boost::enable_if<is_arithmetic<T>, T>::type* = NULL) 
    {} 
}; 

Respuesta

8

Usted puede en cualquier otra función, pero el constructor, porque entonces se puede modificar el nombre de la función incluyendo los argumentos de plantilla.

Foo foo; 
foo.Method<T>(); 

con un constructor, sin embargo, el nombre del constructor nunca aparece en su expresión, así que no hay lugar para poner explícitamente el parámetro de plantilla. Tienes que deducirlo de una discusión.

Foo<T> foo; // no good, assumes the type Foo is a template, not its constructor 
Foo* pfoo = new Foo<T>(); // same problem 

Foo foo((T*)0); // ok, deduced 
Foo* pfoo = new Foo((T*)0); // same 
+0

Si entiendo correctamente, el problema es asegurarse de que la deducción del argumento de la plantilla sea exitosa. Esto se hace creando una instancia explícita de la plantilla con el tipo - foo.Method o haciendo que Method tome un argumento que permita la deducción - template void Método (U * ptr, boost :: enable_if > :: type * = NULL) {} –

+0

@MK: Sí, con la mayoría de las funciones de miembro tiene la opción. Con los constructores, no hay forma de especificar explícitamente los argumentos de la plantilla. –

+0

@MK: con otras funciones, 'enable_if' va muy bien en el valor de retorno, para no alterar la deducción del argumento de la plantilla. Por desgracia, los constructores no tienen un tipo de devolución. OTOH, nadie tomará la dirección de la función constructora y, por lo tanto, nadie se molestará con ese argumento adicional "oculto". – UncleBens

Cuestiones relacionadas