2010-12-30 13 views
6

Bueno me voy a dar un ejemplo sencillo de mi problema:¿Por qué no puedo pasar los parámetros de la plantilla a otra plantilla?

void Increment(Tuple<int, int>& tuple) { 
    ++tuple.Get<0>(); 
} 

int main() { 

    Tuple<int, int> tuple; 

    tuple.Get<0>() = 8; 

    Increment(tuple); 

    printf("%i\n", tuple.Get<0>()); // prints 9, as expected 

    return 0; 

} 

Esto compila bien, y todo es color de rosa. La función Incremento simplemente incrementa el primer elemento en la tupla, y luego imprimo ese elemento. Sin embargo, ¿no sería bueno si mi función Incremento pudiera usarse en cualquier tipo de elemento?

template <typename T> 
void Increment(Tuple<T, T>& tuple) { 
    ++tuple.Get<0>(); // <-- compile ERROR 
} 

int main() { 

    Tuple<int, int> tuple; 

    tuple.Get<0>() = 8; 

    Increment<int>(tuple); 

    printf("%i\n", tuple.Get<0>()); 

    return 0; 

} 

Mi segundo ejemplo escupe el siguiente error en tiempo de compilación:

error: expected primary-expression before ')' token 

Estoy en mis ingenios terminan tratando de averiguar por qué esto causa problemas. Como el parámetro de la plantilla es 'int', el código generado debe ser idéntico a mi ejemplo codificado. ¿Cómo puedo hacer que esto funcione?

+1

La fealdad y la astucia del uso, como se muestra en la respuesta de GMan es probablemente la razón por la cual tanto std e impulsar tuplas tienen una función libre 'GET':' ++ obtener <0> (tupla); ' – UncleBens

Respuesta

11

que debe ser:

++tuple.template Get<0>(); 

De la misma manera que necesita typename para especificar un tipo cualificado de un tipo dependiente, necesita template para especificar una función de plantilla calificado de un tipo dependiente.

+0

¡Ha funcionado brillantemente! No puedo creer que después de todos estos años de usar C++ nunca hubiera escuchado eso. Supongo que no uso plantillas con la suficiente frecuencia. ¡Gracias! – nonoitall

+0

@nonoitall: Es menos conocido, por alguna razón. (También porque muchas personas usan NSVC, ​​y funciona sin él, por lo que la gente nunca se encuentra con el problema en primer lugar.) – GManNickG

+0

@Gman: Sí, es porque MSVC no lo requiere. – Puppy

4

Desde GMan ya le dio la correcta answer, una cosa que todavía se puede hacer es: simplemente hay que escribir Increment(tuple) en lugar de Increment<int>(tuple) (este último sintaxis es un poco complejo). El compilador es lo suficientemente inteligente como para inferir function-template-type del tipo de tuple.

ver esto: http://www.ideone.com/juNOg

+0

Bueno para un comentario. Sospecho que es una retención de él probando varias cosas para que funcione. – GManNickG

Cuestiones relacionadas