如何在编译时漂亮地打印模板参数的名称

Posted

技术标签:

【中文标题】如何在编译时漂亮地打印模板参数的名称【英文标题】:How to pretty print the name of a template parameter at compile time 【发布时间】:2016-09-12 18:08:13 【问题描述】:

问题很简单:如何在 C++ 类中漂亮地打印模板参数的名称并在编译时将其分配给类变量? 似乎typeinfo (typeid) 和 boost::typeindex 都必须在运行时进行评估,或者至少作为其中的一部分进行评估。这显然不允许编译器完全解决包含对该函数之一的调用的constexpr

template<typename T>
class X

   public:
      static const char * name = /* SOME C++ code transforming T in a string (either std::string or char */
;

我错过了什么? 是否只能在运行时生成名称?在那种情况下,我真的需要一个实例化的对象吗?这对我来说似乎不对,因为以下内容在没有任何实例的情况下完美工作:

#include <iostream>
#include <string>
#include <boost/type_index.hpp>

using namespace std;

template<class T>
class X

        public:
                static std::string name()
                
                        return boost::typeindex::type_id<T>().pretty_name();
                
;

struct foobar ;

int main()

        cout << X<int>::name() << endl;
        cout << X<foobar>::name()<< endl;

因此,我不想将name() 作为类方法,而是将其作为类变量。

【问题讨论】:

demangling 是编译时无法完成的。你需要一个静态初始化器,但它会在运行时被调用。 我不认为我的问题是重复的,因为我真的想在编译时这样做。然而,上面的评论给出了为什么constexpr 会失败的第一个线索。你能告诉我为什么不能在编译时进行拆解吗?编译器应该知道模板参数的类型并生成一个名称。我不是试图获取现有对象的类型,而是将类型名称转换为字符串(无论是 std::string 还是 char *) 好吧,我考虑重新打开它并写下我的评论作为答案。如果这会让您更满意,我们可以就这笔交易达成一致。总的来说,我认为将您的问题链接到副本可能对未来的研究更有用,这很好地说明了为什么在编译期间无法完成。 如你所愿。我对您的评论和其他答案感到满意。感谢您的帮助:我知道我现在需要知道什么。 您可以从投票中看到,重复的问题不会被视为无用的第一名。就像您的问题一样,这些可能是未来研究的好路标。 【参考方案1】:

我认为,可以使用自定义类型特征。请看下一个例子:

#include <iostream>
#include <string>

using namespace std;

//Using stub type traits
template <class T>
struct TypeTraits;

//your TypeTraits for specific types...
template<>
struct TypeTraits<int>

    constexpr static const char *name = "int";
;

template<class T>
class X

    public:
            constexpr static const char * name = TypeTraits<T>::name;
;

struct foobar ;

//TypeTraits for custom  foobar
template<>
struct TypeTraits<foobar>

    constexpr static const char *name = "foobar";
;


int main()

    //Now you can use static member here
    cout << X<int>::name << endl;
    cout << X<foobar>::name<< endl;

TypeTraits 也可以用于(和扩展)其他用途。

【讨论】:

以上是关于如何在编译时漂亮地打印模板参数的名称的主要内容,如果未能解决你的问题,请参考以下文章

当使用 Spring MVC for REST 时,如何让 Jackson 漂亮地打印呈现的 JSON?

通过索引对类模板成员的编译时访问

gcc 编译带有大量模板参数的模板类时出错

使用 C++11 可变参数模板在编译时快速排序

Makefile编译时怎么打印出变量值

编译时内的模板参数展开for循环?