在下面的代码中,当注释掉代码代码时,代码按预期工作 - Type
匹配(第一个)模板参数。
但是,如果我取消注释,Type
将变为char
而不是std::string
。 MSVC和GCC都是一样的。因此,当我对具有一个和两个参数的标签模板进行StripTag
专门化时,它会起作用,但是当我以完全相同的方式对三个参数进行专门化时,我会得到这种奇怪的行为。
任何人都有任何想法?
代码如下:
#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 :(得分:3)
这是因为std::string
实际上只是
std::basic_string<char, std::char_traits<char>, std::allocator<char>>
如您所见,这是一个包含三个类型参数的类模板。
如果你有一个StripTag
专门化,它将一个三参数类模板作为其参数之一,那么该专业化比std::string
更好地匹配主类模板(因为它更具体)。