2009-09-18 12 views
5

un parámetro de plantilla se puede utilizar en otro parámetro de plantilla que sigue de esta manera:Cómo utilizar un parámetro de plantilla en otro parámetro de plantilla declarado ante

template<typename T, T N> 
struct s 
{ 
}; 

Pero es posible hacer referencia a "T" si se trata de declarado después de "N"?

Esto no funciona:

template<T N, typename T> 
struct s 
{ 
}; 

Podemos ayudar al compilador mediante pre-declarando "T" o hacer cualquier otra cosa?

Gracias por adelantado.

EDITAR: como las dos primeras respuestas preguntaban "¿por qué estás dispuesto a hacer eso?" Explicaré el objetivo:

Me gustaría hacer que el compilador infiera el tipo "T" para facilitar el uso de clases con plantilla.

Por ejemplo:

template<typename T, T A, T B> 
struct sum 
{ 
    static T const value = A + B; 
}; 

Esta plantilla se puede utilizar de esta manera:

sum<int, 1, 2>::value 

Pero sería mejor si pudiera ser utilizado de esta manera:

sum<1, 2>::value 

Técnicamente debe ser posible porque el compilador conoce los tipos de "1" y "2": "int", y de hecho usa estos inf ormaciones para encontrar la mejor sobrecarga para una función. Así declarando la plantilla de esta manera:

template<T A, T B, typename T> 
struct sum 
{ 
    static T const value = A + B; 
}; 

el compilador podría utilizar su capacidad de inferir el último parámetro de las informaciones proporcionadas por el primer y el segundo, y luego encontrar la mejor plantilla para crear una instancia.

Respuesta

6

Al igual que otros dicen - No, esto no es posible, el compilador no puede deducir el tipo de T del tipo no- plantilla de argumentos (en el caso de funciones, se infiere tipos de la función argumentos):

14.8.2.4/12: argumento de tipo

una plantilla no puede deducirse a partir del tipo de un no-tipo de plantilla-argumento.

En cualquier caso, de todos modos, no se harán deducciones por los argumentos de una plantilla de clase. Un ejemplo de una plantilla de función podría ser

template<int> struct having_int { }; 
template<typename T, T i> void f(having_int<i>); 
int main() { having_int<0> h; f(h); } 

En este caso, T no se deducirá como int - tiene que especificar explícitamente.

+0

Gracias por la respuesta: si la norma dice no, es no. La pregunta ahora es: ¿por qué este comportamiento limitado mientras que parece posible hacer esta deducción? ¿Tiene algunos ejemplos que justifiquen esta decisión? Gracias. – Pragmateek

+0

¿Porque la metaprogramación de plantillas nunca fue pensada para ser expresiva? :) Interesante pregunta, sin embargo. Puede ser que deba verificar si esto ha sido propuesto, o hacer esa proposición para C++ 1x. – UncleBens

0

No puede. No entiendo por qué lo haces también.

0

A continuación está la basura ya que no leí su pregunta correctamente.

De hecho, tampoco veo ningún punto en lo que estás tratando de lograr.

#include <iostream> 

template<typename T, T N> 
struct s 
{ 
    T size() { return N; } 
}; 


int main() 
{ 
    s<int, 4> x; 
    std::cout << x.size()<< '\n'; 

    //s<float, 3.14> f; //this doesn't compile 
} 

Esto compila para mí con GCC y Comeau en línea.

Creo que el problema es con el tipo de T que está intentando usar. Los argumentos de plantilla sin tipo solo admiten tipos integrales, y luego apuntan a objetos con enlaces externos (o algo así y quizás algunas otras cosas muy limitadas).

Cuestiones relacionadas