【问题标题】: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 *)
  • 好吧,我考虑重新打开它并写下我的评论作为答案。如果这会让您更满意,我们可以就这笔交易达成一致。总的来说,我认为将您的问题链接到副本可能对未来的研究更有用,这很好地说明了为什么在编译期间无法完成。
  • 如你所愿。我对您的评论和其他答案感到满意。感谢您的帮助:我知道我现在需要知道什么。
  • 您可以从投票中看到,重复的问题不会被视为无用的第一名。就像您的问题一样,这些可能是未来研究的好路标。

标签: c++ templates c++11 boost


【解决方案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 也可以用于(和扩展)其他用途。

【讨论】:

    猜你喜欢
    • 2015-09-16
    • 2012-12-15
    • 2015-01-22
    • 1970-01-01
    • 1970-01-01
    • 2021-09-01
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多