2012-12-30 15 views
12

typeid(T).name()は型の人間が理解できる名前を返さないので、テンプレート引数の名前を何らかのクラスに出力したい場合はあまり役に立ちませんテンプレート、特に私たちがデバッグしているとき。すべてのテンプレート引数と一緒にきれいな印刷タイプとクラステンプレート

print<Args...>(cout); //dump the names of all types to stdout! 

私はクラステンプレートの名前を教えてくれるpretty-printユーティリティを書いています。まあ、いくつかのサンプルの使用を通してそれを理解することは簡単です:内部

print<int>(cout);    //prints int 
print<int, double, char>(cout); //prints int, double, char 
print<std::string>(cout);  //prints std::basic_string<char, .. etc> 
print<std::wstring>(cout);  //prints std::basic_string<wchar_t, .. etc> 
print<X<int,Y<int>>>(cout);  //prints X<int, Y<int>> 

、私はテンプレート引数としてそれにY<int>を渡すとき、私に"Y"を返しtemplate_nameというクラステンプレートを使用しています。ここでは、それが各ユーザークラステンプレートに対して部分的に特化されている方法を示します。専門template_name<template_type<Ts...>>はそれを意味し、種類のみの可変長引数クラステンプレートであるため、作品

DEFINE_TEMPLATE_NAME(std::basic_string); 
DEFINE_TEMPLATE_NAME(std::vector); 
DEFINE_TEMPLATE_NAME(X); //X is a class template 
DEFINE_TEMPLATE_NAME(Y); //Y is a class template 

#define DEFINE_TEMPLATE_NAME(template_type) \ 
template<typename ... Ts>\ 
struct template_name<template_type<Ts...>>\ 
{\ 
    static const char* name()\ 
    {\ 
     return #template_type;\ 
    }\ 
}; 

し、ユーザーは次のように彼のテンプレートクラスを登録するには、このマクロを使用する必要がありますクラステンプレートの名前を返します。すべてのテンプレートパラメータはタイプです。また、同様の機能-種類とメンバー関数の型を印刷することができる:

typedef void fun(int,int); 

//lets use snl::name() which returns name instead of printing! 
std::cout << snl::name<fun>(); //prints : void(int,int) 
std::cout << snl::name<fun*>(); //prints : void(*)(int,int) 

他の分の詳細をthe working code hereを参照してください。これまでのところ素晴らしいです。

しかし、今、私はこれで改善し、非種類のサポートを追加したいんだが、同様の引数と混合テンプレート引数をtempate:

template<int...> 
struct Z{}; 

//non-type template arguments : 1,2,3 
snd::print<Z<1,2,3>>(cout); //should print Z<1,2,3> 

//mixed template arguments : int, 100 
snd::print<std::array<int,100>>(cout); //should print std::array<int,100> 

はどのように私はそれを行うのでしょうか?そのようなクラステンプレートの名前とその引数を総称してどのように取得するのですか?

+5

GCCには非常に便利なテンプレートクラス名を出力するデングングラーがあります。 –

+0

@KerrekSB:はい、それは標準ではありません。どこでもうまくいくものが欲しい。 – Nawaz

答えて

6

申し訳ありませんが、これは "否定的な回答"です(私はあなたの質問をupvotingしています)が、私はあなたがそれを行うことができないことを恐れています。でも非型パラメータ(例えばなどtemplate<int, int>template<char, char, char>、)の均質なリストを受け入れるだけのテンプレートクラスを考慮すると、あなたはこの種の専門分野が必要になります。

template<typename T> 
struct single_type 
{ 
    // ... 
}; 

template<typename U, template<U...> class C, U... Us> 
struct single_type<C<Us...>> 
{ 
    // ... 
}; 

この分業は、引数の型のため、法的けど役に立ちませんUは推測できません。最も一般的な型(int...char...など)のリテラルの統一リストに対して専用の特殊化を定義することもできますが、混在する引数のシーケンスはもちろん、異種型のシーケンスをカバーすることはできません。

あなたが探しているものを達成するために、C++がリフレクションをサポートするのを待つ必要があります。

関連する問題