は人間が理解できる型の名前を返さないためtypeid(T).name()
、テンプレート引数の名前をクラステンプレートに出力したい場合、特にデバッグ中にはあまり役に立ちません。デバッグでこれを書きたいと思うことがよくあります。
print<Args...>(cout); //dump the names of all types to stdout!
そこで、クラス テンプレートの名前を表示するプリティ プリント ユーティリティを作成しています。まあ、いくつかのサンプル使用法を通してそれを理解するのはより簡単です:
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>>
内部的には、テンプレート引数として渡すtemplate_name
と返されるというクラス テンプレートを使用しています。ここでは、ユーザー クラス テンプレートごとに部分的に特化する方法を示します。"Y"
Y<int>
#define DEFINE_TEMPLATE_NAME(template_type) \
template<typename ... Ts>\
struct template_name<template_type<Ts...>>\
{\
static const char* name()\
{\
return #template_type;\
}\
};
そして、ユーザーはこのマクロを使用してテンプレート クラスを次のように登録する必要があります。
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
特殊化は型template_name<template_type<Ts...>>
のみの可変引数クラス テンプレートであるため、これは機能します。つまり、すべてのテンプレート パラメーターがtypesである限り、クラス テンプレートの名前が返されます。関数型とメンバー関数型も出力できます。
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)
その他の詳細については、こちらの作業コードを参照してください。それはこれまでのところうまくいきます。
しかし今、私はこれを改善しており、型以外のテンプレート引数と混合テンプレート引数のサポートも追加したいと考えています:
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>
どうすればいいですか?そのようなクラステンプレートの名前とその引数を一般的に取得するにはどうすればよいですか?