Normalmente declaro mis clases y plantillas, y luego defino sus métodos después (en el mismo archivo de encabezado, por supuesto). Simplemente me resulta más fácil leer de esa manera. Bueno, me he encontrado con un caso en el que no puedo encontrar una firma de tipo de trabajo para usar en una definición fuera de clase. Aquí está un ejemplo simplificado de lo que estoy haciendo, que ilustra el problema:¿firma de tipo de un constructor de plantilla con plantilla habilitada?
template <class T>
struct Foo
{
Foo(T a, T b);
template
< class Iterator
, enable_if< is_iterator<Iterator> >
>
Foo
(Iterator first
, Iterator last
);
};
template <class T>
Foo<T>::Foo(T a, T b)
{ ... }
template <class T>
template
< class U
, WHAT_GOES_HERE?
>
Foo<T>::Foo(U f, U l)
{ ... }
He intentado varias cosas en la ranura WHAT_GOES_HERE
para tratar de obtener una firma coincidente, y me siguen fallando. Necesito el enable_if para distinguir el caso donde uno pasa en dos objetos de tipo T, y cuando uno pasa en un par de iteradores. El código funciona bien si el constructor con plantilla se define dentro de la plantilla principal, que es como lo hace actualmente el código, pero prefiero mover la definición fuera de la declaración.
EDIT: debería mencionar que no puedo volver a utilizar enable_if < ...> en la definición, porque enable_if < ...> asigna un valor predeterminado para su tipo, que no se puede hacer en una definición que no es también una declaración.
lo que realmente necesita SFINAE para esto? Si declara el segundo constructor como 'plantilla Foo (U primero, U último);', el primer constructor seguirá siendo seleccionado si la persona que llama pasa dos objetos de tipo 'T'. –
Tipo T es generalmente un tipo aritmético, y quiero poder pasar ints cuando T no está firmado y viceversa, y no tener el constructor con plantilla llamado (lo que estaba sucediendo antes de usar el enable_if) – swestrup
En realidad, no estás asignando un valor predeterminado en absoluto. El segundo parámetro para su plantilla es 'enable_if>'. Más o menos como si esperaras un 'int'. No debería compilarse y ciertamente sería imposible de usar. –