2010-06-21 5 views
3

Donc, étant donné les fonctions de modèle suivantes avec spécialisation partielleOrdre partiel C de échoue avec 2 paramètres de modèle

template<typename T> 
void foo(vector<T> &in) { 
    cout << "vector" << endl; 
} 

template<typename T> 
void foo(T &in) { 
    cout << "scalar" << endl; 
} 

int main(int arc, char *argv[]) { 
    vector<double> a; 
    double b; 

    foo(a); 
    foo(b); 
    return 0; 
} 

Je n'ai aucun problème compilation avec g ++ 3.4.6 et obtenir le résultat attendu:

vector 
scalar 

maintenant, si j'ajoute un second paramètre de modèle:

template<class U, typename T> 
void foo2(vector<T> &in) { 
    U a; 
    cout << "vector" << endl; 
} 

template<class U, typename T> 
void foo2(T &in) { 
    U a; 
    cout << "scalar" << endl; 
} 

et appelle le suivi ING:

int main(int arc, char *argv[]) { 
    vector<double> a; 
    double b; 

    foo2<double>(a); 
    foo2<double>(b); 
    return 0; 
} 

Lorsque j'essaie de le compiler, GCC 3.4.6 me donne une erreur de surcharge ambiguë. Je ne vois pas comment le deuxième paramètre de modèle rend maintenant la surcharge ambiguë. Autant que je sache, la version vectorielle devrait être encore plus spécialisée. Est-ce juste un bug dans 3.4? Y at-il un travail autour? Pour l'enregistrement, le code fonctionne dans gcc 4.1 sans problème. Malheureusement, certains de nos outils sont toujours liés à 3.4, de sorte que la mise à niveau n'est pas la solution.

Merci.

+0

Est-ce que gcc 3.4 fonctionne correctement lorsque vous donnez explicitement tous les arguments du modèle? – andand

+0

Aussi, le titre de ceci est trompeur. L'ordre partiel a une signification mathématique spécifique. Ce dont vous parlez, c'est la spécification partielle d'un modèle. – andand

+3

De plus, ce n'est même pas une spécialisation partielle. Seules les classes peuvent être partiellement spécialisées. Les fonctions du modèle sont surchargées. – Cogwheel

Répondre

2

Cela semble être lié à this defect qui est fixed dans la dernière version du compilateur. Les solutions de contournement consistent à définir explicitement tous les arguments du modèle ou à utiliser functor à la place:

template<typename U> 
struct foo2 { 
    template<typename T> 
    void operator()(std::vector<T> &in) { 
     U a; 
     cout << "vector" << endl; 
    } 
    template<typename T> 
    void operator()(T& in) { 
     U a; 
     cout << "scalar" << endl; 
    } 
}; 

int main(int arc, char *argv[]) { 
    vector<double> a; 
    double b; 

    foo2<double>()(a); 
    foo2<double>()(b); 
    return 0; 
} 
+0

Merci. J'ai vu ce rapport de bogue lors de mes recherches mais cela ne m'a pas vraiment permis de travailler. Utiliser le foncteur semble avoir résolu mon problème. Merci encore. – asinclair