2012-01-11 18 views
1

以下のコードでは、意味のあるコードがコメントアウトされると、コードは期待通りに機能します。Typeは(最初の)テンプレート引数に一致します。次のテンプレートコードの奇妙な動作

ただし、コメントを外すとstd::stringではなくcharとなります。これはMSVCとGCCの両方で同じです。だから、私はStripTagの特殊化を1つと2つの引数を持つタグテンプレートに使用していますが、3つの引数に対してまったく同じ方法で特殊化すると、この奇妙な動作が発生します。

誰にでもアイデアはありますか?

コードは次のとおりです。

#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

[タグ:c]タグが削除されました。これは純粋なC++コードです。 – Xeo

答えて

3

これはstd::string

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

このため実際には単なるtypedefであるので、あなたが見ることができるように、3種類のパラメータを持つクラステンプレートです。

パラメータの3つとして3つのパラメータのクラステンプレートを使用するStripTagの特殊化を使用している場合、その特殊化はプライマリクラスのテンプレート(std::string)に適しています(より具体的です)。

+0

Ohhh :)はい、私はそれについて完全に忘れました。これですべてが説明されます。どうもありがとう –