54 votes

C ++, l'argument de modèle ne peut pas être déduit

Quel est le problème dans ce code?

 #include <map>

template<typename T>
struct TMap
{
    typedef std::map<T, T> Type;
};

template<typename T>
T test(typename TMap <T>::Type &tmap_) { return 0.0; }

int _tmain(int argc, _TCHAR* argv[])
{
    TMap<double>::Type tmap;
    tmap[1.1] = 5.2;
    double d = test(tmap); //Error: could not deduce template argument for T
    return 0;
}
 

86voto

Nawaz Points 148870

Qui est non-ressort contexte. C'est pourquoi l'argument de modèle ne peut pas être déduite par le compilateur.

Imaginez, vous pourriez avoir spécialisée TMap comme suit:

template <>
struct TMap<SomeType>
{
    typedef std::map <double, double> Type;
};

Comment le compilateur déduire le type SomeType, étant donné qu' TMap<SomeType>::Type est std::map<double, double>? Il ne peut pas. Ce n'est PAS garanti que le type que vous utilisez, en std::map est également le type en TMap. Le compilateur ne peut pas faire ce dangereux hypothèse. Il peut ne pas y aucune relation entre le type d' arguments, que ce soit.

Aussi, vous pourriez avoir d'autres spécialisation de l' TMap défini comme:

template <>
struct TMap<OtherType>
{
    typedef std::map <double, double> Type;
};

Cela rend la situation encore pire. Maintenant que vous avez les éléments suivants:

  • TMap<SomeType>::Type = std::map<double, double>.
  • TMap<OtherType>::Type = std::map<double, double>.

Maintenant demandez-vous: donnée TMap<T>::Type est std::map<double, double>, comment le compilateur de savoir si T est SomeType ou OtherType? Il ne peut même pas savoir combien de ces choix qu'elle a, ni ne peut-il connaître les choix eux-mêmes.. je suis juste vous demander, pour l'amour de la pensée-expérience (en supposant qu'il peut connaître l'ensemble des choix).

3voto

James Kanze Points 96599

Exactement ce que le message d'erreur du compilateur dit: en TMap<T>::Type , T n'est pas déductible selon la norme. La raison en est probablement qu’il n’est techniquement pas possible de le mettre en oeuvre: le compilateur devrait instancier tous les TMap<T> pour voir si un (et un seul) correspond au type que vous avez transmis. Et il existe un nombre infini de TMap<T> .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X