本文介绍了漂亮打印类型和类模板及其所有模板参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

由于 typeid(T).name()不返回人类可以理解的类型名称,如果我们打印名字的模板参数到一些类模板,特别是当我们调试。我们经常想在调试时写这个:

Since typeid(T).name() doesn't return human understandable name of the type, it doesn't help us much if we want to print the name of the template arguments to some class template, especially when we're debugging. We often feel like writing this in debugging:

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

所以我写的漂亮打印实用程序,它给我类模板的名称。好吧,通过一些示例用法更容易理解:

So I'm writing pretty-print utility which gives me the name of the class template. Well, it is easier to understand it through some sample usage:

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< int> 作为模板参数时,它返回我Y以下是每个用户类模板的部分专用。

Internally, I'm using a class template called template_name which returns me "Y" when I pass Y<int> to it as template argument. Here is how it is partially specialized for each user class template.

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

并且用户需要使用此宏来注册他的模板类:

And the user is required to use this macro to register his template class as:

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 ...> 类型上的可变类模板,这意味着它将返回类模板的名称, / strong>,所有模板参数都是类型。它也能够打印函数类型和成员函数类型:

That works because the specialization template_name<template_type<Ts...>> is a variadic class template on types only, which means it would return me the name of class template as long as all the template parameters are types. It is also able to print function-types and member-function-types as well:

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)

请参阅与其他详细信息。

Please see the working code here with other minute details. That works great so far.

但现在我正在改进这一点,并希望添加对非类型临时参数和混合的支持。模板参数:

But now I'm improving on this, and want to add support for non-types tempate arguments and mixed template arguments as well:

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>

我该怎么办?我如何获得这样的类模板及其参数的名称一般?

How would I do that? How do I get the name of such class template and its arguments generically?

推荐答案

对不起,这是一个 (我正在考虑你的问题),但恐怕你不能这样做。即使仅考虑接受非类型参数的同类列表的模板类(例如 template< int,int> template< char,char,char> 等),您将需要这种特殊化:

I'm sorry this is a "negative answer" (I am upvoting your question), but I'm afraid you cannot do that. Even considering only template classes which accept homogeneous lists of non-type parameters (e.g. template<int, int>, template<char, char, char>, etc.), you would need a specialization of this kind:

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

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

这种特殊化是合法的,但是没有用,因为参数类型 U 永远不能推断。您可以为最常见类型的字面量统一列表定义专用特殊化( int ... char ... 等),但是仍然不可能覆盖异质类型的序列,更不用说混合参数的序列。

This specialization is legal but useless, because argument type U can never be deduced. You may define dedicated specializations for uniform lists of literals of the most common types (int..., char..., etc.), but it would still be impossible to cover sequences of heterogeneous types, let alone sequences of mixed arguments.

恐怕我们必须等待C ++支持反射,以实现你正在寻找的东西。

I'm afraid we'll have to wait for C++ to support reflection in order to achieve what you're looking for.

这篇关于漂亮打印类型和类模板及其所有模板参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-10 12:14