2012-01-11 2 views
1

Dans le code ci-dessous, lorsque le code signifié est mis en commentaire, le code fonctionne comme prévu - Type correspond au (premier) argument du modèle.Comportement étrange du code modèle suivant

Cependant, si je ne le décommente pas, Type devient char au lieu de std::string. C'est la même chose avec MSVC et GCC. Donc, cela fonctionne quand j'ai la spécialisation de StripTag pour un modèle d'étiquette avec un et deux arguments, mais quand je le spécialise exactement de la même manière pour trois arguments, j'ai ce comportement étrange.

Quelqu'un a des idées?

Code suit:

#include <typeinfo> 
#include <stdio.h> 
#include <string> 

template <typename T> 
struct StripTag 
{typedef T Type;}; 

template<typename T, template<typename T> class Tag > 
struct StripTag<Tag<T> > 
{ typedef typename StripTag<T>::Type Type; }; 

template<typename T, typename X, template<typename T, typename X> class Tag > 
struct StripTag<Tag<T,X> > 
{ typedef typename StripTag<T>::Type Type; }; 

/* 
//UNCOMMENT THIS AND RECOMPILE 
template<typename T, typename X, typename Y, template<typename T, typename X, typename Y> class Tag > 
struct StripTag<Tag<T,X,Y> > 
{ typedef typename StripTag<T>::Type Type; }; 
*/ 

template <class C> 
struct Test 
{ 
typedef C Type; 
}; 

template <typename A, typename B> 
struct Blah{}; 

int main() 
{ 

    printf("typeid of StripTag=\t%s\n", typeid(StripTag<std::string>::Type).name()); 
    printf("typeid of StripTag2=\t%s\n", typeid(StripTag<Blah<std::string, bool> >::Type).name()); 
    printf("typeid of Test=\t\t%s\n", typeid(Test<std::string>::Type).name()); 
    printf("typeid of std::string=\t%s\n", typeid(std::string).name()); 
} 
+0

Balise [tag: c] supprimée, car il s'agit d'un code C++ pur. – Xeo

Répondre

3

C'est parce que std::string est vraiment juste un typedef pour

std::basic_string<char, std::char_traits<char>, std::allocator<char>> 

, comme vous pouvez le voir, est un modèle de classe avec trois paramètres de type. Lorsque vous avez une spécialisation StripTag qui prend un modèle de classe à trois paramètres comme l'un de ses paramètres, cette spécialisation est une meilleure correspondance pour std::string que le modèle de classe primaire (parce qu'il est plus spécifique).

+0

Ohhh :) Oui, j'ai complètement oublié ça. Cela explique tout. Merci beaucoup –