2009-11-17 4 views
1

J'ai essayé de faire ce truc simple et Visual Studio 2008 ne semble pas l'aimer.Fonction de modèle avec les paramètres de type dépendants dans la classe de modèle

template <class CharType> 
class SomeClass 
{ 
public: 
    template <class T1, class T2> 
    static bool SomeOperator(const typename T1::const_iterator& p_Begin1, 
          const typename T1::const_iterator& p_End1, 
          const typename T2::const_iterator& p_Begin2, 
          const typename T2::const_iterator& p_End2) 
    { 
     // do some stuff.. 
    } 
}; 

Et l'appeler avec quelque chose comme ceci:

std::wstring a; 
OtherString b; 
SomeClass<wchar_t>::SomeOperator(a.begin(), a.end(), b.begin(), b.end()); 

Ce que je reçois est des erreurs du compilateur indiquant qu'il ne peut pas en déduire le paramètre de modèle T1 et T2

error C2783: 'bool SomeClass<CharType>::SomeOperator(const T1::const_iterator &,const T1::const_iterator &,const T2::const_iterator &,const T2::const_iterator &)' : could not deduce template argument for 'T1' 
error C2783: 'bool SomeClass<CharType>::SomeOperator(const T1::const_iterator &,const T1::const_iterator &,const T2::const_iterator &,const T2::const_iterator &)' : could not deduce template argument for 'T2' 
+0

Est-ce que la compilation de code lorsque vous définissez explicitement le paramètre de modèle? Donc, comme 'SomeClass :: SomeOperator (a.begin(), a.end(), b.begin(), b.end());' – pkit

Répondre

3

Le compilateur est simplement incapable de déduire des types de ce contexte.

Supposons que std::wstring::const_iterator est réellement const wchar_t*, ce qui est probable. Dans ce cas, comment le compilateur sait-il qu'il doit remplacer std::wstring plutôt que tout autre type T avec T::const_iterator étant const wchar_t* (peut-être vector<wchar_t>)?

Il est impossible pour le compilateur de dire exactement. Pour des raisons similaires, vous ne pouvez pas déduire some_template<T>::type dans les appels de fonction.

Dans votre cas, la solution de contournement est facile. Vous n'avez pas réellement besoin du type de conteneur - templating sur les types iterator fonctionnera très bien:

template <typename I1, typename I2> 
static bool SomeOperator(const I1& p_Begin1, const I1& p_End1, 
         const I2& p_Begin2, const I2& p_End2) 
    { /* stuff */ } 

Si vous vous trouvez dans une situation où vous avez besoin du type de conteneur, vous devrez soit passer le récipient autour ou spécifiez explicitement le type dans l'appel de fonction.

+0

C'est ce que j'avais trouvé mais c'était en quelque sorte une solution insatisfaisante .. –

0

Vous avez probablement besoin être explicite sur les types pour SomeOperator:

SomeClass<wchar_t>::SomeOperator<std::wstring, std::wstring>(a.begin(), a.end(), b.begin(), b.end()); 

Je sais que cela semble ennuyeux, mais il est en fait assez difficile (et parfois impossible) pour le compilateur de déduire le type de conteneur d'une définition imbriquée comme T::const_iterator. Aller de const_iterator à T n'est pas simple AFAIK.

1

Le compilateur ne peut pas déduire que les paramètres de l'itérateur sont en réalité des défauts de type interne des conteneurs qui les fournissent.

Utilisez directyl deux types iterator:

template< typename IT1, typename IT2> 
static bool SomeOperator(const IT1& p_Begin1, 
          const IT1& p_End1, 
          const IT2& p_Begin2, 
          const IT2& p_End2) 
    { 
     // do some stuff.. 
    } 
Questions connexes