2009-09-18 10 views
5

un paramètre de modèle peut être utilisé dans un autre paramètre de modèle qui suit ainsi:Comment utiliser un paramètre de modèle dans un autre paramètre de modèle déclaré avant

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

Mais est-il possible de faire référence à « T » si elle est déclaré après "N"?

Cela ne fonctionne pas:

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

Pouvons-nous aider le compilateur en pré-déclarant « T » ou faire autre chose?

Merci d'avance.

EDIT: comme les deux premières réponses demandaient "pourquoi êtes-vous prêt à faire cela?" Je vais vous expliquer l'objectif:

Je voudrais que le compilateur infère le type "T" afin de faciliter l'utilisation de classes modélisées.

Par exemple:

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

Ce modèle peut être utilisé de cette façon:

sum<int, 1, 2>::value 

Mais ce serait mieux si elle pouvait être utilisé de cette façon:

sum<1, 2>::value 

Techniquement il devrait être possible parce que le compilateur connaît les types de "1" et "2": "int", et en fait, il utilise ces inf ormations pour trouver la meilleure surcharge pour une fonction. Ainsi, en déclarant le modèle de cette façon:

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

le compilateur pourrait utiliser sa capacité de déduire le dernier paramètre à partir des informations fournies par le premier et le second, puis trouver le meilleur modèle pour instancier.

Répondre

6

Comme d'autres disent - Non, ce n'est pas possible, le compilateur ne peut pas déduire le type de T de la non type modèle arguments (dans le cas des fonctions, il infère types de la fonction arguments):

14.8.2.4/12:

un argument de type de modèle ne peut pas être déduit à partir du type d'un modèle argument non type.

Dans tous les cas, aucune déduction ne sera faite pour les arguments d'un modèle de classe. Un exemple pour un modèle de fonction peut être

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

Dans ce cas, T ne sera pas déduit que int - vous devez spécifier explicitement.

+0

Merci pour la réponse: si la norme dit non, c'est non. La question est maintenant: pourquoi ce comportement limité alors qu'il semble possible de faire cette déduction? Avez-vous quelques exemples justifiant cette décision? Merci. – Pragmateek

+0

Parce que la métaprogrammation de modèle n'a jamais été conçue pour être expressive? :) Question intéressante, cependant. Peut-être vous devriez vérifier si cela a été proposé, ou faire cette proposition pour C++ 1x. – UncleBens

0

Vous ne pouvez pas. Je ne vois pas pourquoi vous le faites aussi.

0

Ci-dessous est des ordures comme je n'ai pas lu votre question correctement.

En effet, je ne vois aucun point dans ce que vous essayez d'accomplir non plus.

#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 
} 

Cela se compile pour moi avec GCC et Comeau Online. Je pense que le problème est avec le type de T que vous essayez d'utiliser. Les arguments de modèle non-type ne supportent que les types entiers, puis les pointeurs vers des objets avec un lien externe (ou quelque chose comme ça et peut-être quelques autres choses très limitées).

Questions connexes