如何在编译时漂亮地打印模板参数的名称
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 也可以用于(和扩展)其他用途。
【讨论】:
以上是关于如何在编译时漂亮地打印模板参数的名称的主要内容,如果未能解决你的问题,请参考以下文章