Naw*_*waz 12 c++ templates pretty-print variadic-templates c++11
由于typeid(T).name()不返回类型的人类可理解的名称,如果我们想要将模板参数的名称打印到某个类模板,它对我们没什么帮助,特别是在我们调试时.我们经常想在调试中写这个:
print<Args...>(cout); //dump the names of all types to stdout!
Run Code Online (Sandbox Code Playgroud)
所以我正在编写漂亮的打印工具,它给了我类模板的名称.嗯,通过一些示例用法更容易理解它:
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>>
Run Code Online (Sandbox Code Playgroud)
在内部,我正在使用一个名为模板的模板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;\
}\
};
Run Code Online (Sandbox Code Playgroud)
并且用户需要使用此宏来将其模板类注册为:
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
Run Code Online (Sandbox Code Playgroud)
这是有效的,因为专门化template_name<template_type<Ts...>>只是类型上的可变参数类模板,这意味着只要所有模板参数都是类型,它就会返回类模板的名称.它还能够打印函数类型和成员函数类型:
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)
Run Code Online (Sandbox Code Playgroud)
请参阅此处的工作代码以及其他细节.到目前为止,这很有效.
但是现在我正在改进这个,并希望添加对非类型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>
Run Code Online (Sandbox Code Playgroud)
我该怎么办?如何获取此类模板及其参数的名称?
对不起,这是一个"否定回答"(我正在回答你的问题),但我担心你不能这样做.即使只考虑接受非类型参数(例如同质列表模板类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...>>
{
// ...
};
Run Code Online (Sandbox Code Playgroud)
这种专业化是合法的,但没用,因为U永远不能推断出参数类型.您可以为最常见类型(int...,char...等)的文字的统一列表定义专用特化,但是仍然不可能覆盖异构类型的序列,更不用说混合参数的序列.
我担心我们必须等待C++支持反射才能实现你想要的东西.
| 归档时间: |
|
| 查看次数: |
1440 次 |
| 最近记录: |