2010-06-21 5 views
4

le code suivant est un exemple de quelque chose que je suis en train de le faire dans un grand projet:modèles de fonction avec des arguments de modèle de classe typedef

#include <iostream> 
#include <vector> 

// standard template typedef workaround 
template<typename T> struct myvar {typedef std::vector<T> Type;}; 

template<typename T> 
T max(typename myvar<T>::Type& x) 
// T max(std::vector<T>& x) 
{ 
    T y; 
    y=*x.begin(); 
    for(typename myvar<T>::Type::iterator it=x.begin(); it!=x.end(); ++it) 
    if(*it>y) 
     y=*it; 
    return y; 
} 

int main(int argc, char **argv) 
{ 
    myvar<int>::Type var(3); 
    var[0]=3; 
    var[1]=2; 
    var[2]=4; 
    std::cout << max(var) << std::endl; 
    return 0; 
} 

Lorsque je tente de compiler je reçois:

>g++ delme.cpp -o delme 
delme.cpp: In function ‘int main(int, char**)’: 
delme.cpp:25: error: no matching function for call to ‘max(std::vector<int, std::allocator<int> >&)’ 

Cependant, si je commente la ligne 8 et ligne 9 uncomment il compile correctement et donne:

>g++ delme.cpp -o delme 
>./delme 
4 

quelqu'un peut-il expliquez pourquoi la définition de modèle de fonction de max() en utilisant typename myvar<T>::Type& n'est pas considérée comme une correspondance pour ‘max(std::vector<int, std::allocator<int> >&)’ et est-il possible de la faire correspondre sans utiliser le type std::vector<T>& sous-jacent?

Répondre

5

Il est impossible de déduire le type d'élément englobant (ou tout attribut du type englobant) de son type imbriqué. C'est l'un des exemples de ce que l'on appelle le contexte non déduit en C++. Bien que la déclaration de la fonction de modèle elle-même soit légale, vous ne pourrez pas appeler votre fonction comme max(var) puisque la déduction de l'argument de modèle ne peut pas être effectuée. Dans votre cas, le compilateur ne sera pas en mesure de comprendre que le paramètre x de type std::vector<int> implique que T est myvar<int>.

Vous devez toujours spécifier des arguments de modèle pour max explicitement, comme dans

std::cout << max<int>(var) << std::endl; 

Comment contourner ce problème dépend de ce que vous essayez d'atteindre en introduisant ce modèle renfermant myvar.

+0

Je vois, merci. La raison de la 'modèle de myvar' est d'utiliser des matrices column_major dans uBLAS sans que l'utilisateur de toujours spécifier ce, à savoir, espace de noms Cheb { modèle matrice struct { typedef boost :: :: uBLAS numériques: : matrice type; }; } Je veux alors que mes fonctions aient des arguments de type 'Cheb :: matrix :: type'. Je n'ai pas trop de fonctions basées sur des modèles, donc je peux survivre en spécifiant explicitement mes arguments de template, mais ce serait bien de ne pas avoir à le faire. –

+0

Si l'appel de Max() est également un modèle, les paramètres de ce modèle peuvent-ils être passés en tant que paramètres du modèle à Max() - cela résoudrait-il le type? – fusi

1

Au lieu de le coder vous-même, avez-vous envisagé d'utiliser std::max_element à la place? Il faut un itérateur de début et de fin et je crois que c'est ce que vous voulez ici.

+0

Merci, mais j'utilisais 'max()' comme exemple. J'ai d'autres fonctions où le même problème se produit. Je vais garder à l'esprit 'std :: max_element' pour la prochaine fois que je veux un maximum si ... :-) –

Questions connexes