如何在c ++中将typename T转换为string

Sri*_*nth 59 c++ templates

在c ++中使用模板时,我遇到了将typename T转换为string的问题.例如:

template <typename T>
class Matrix {
   public:
        Matrix() {
           //my_type = string type of T. i.e. if T is char. I want my_type to be "char".
        }
   string my_type;
}
Run Code Online (Sandbox Code Playgroud)

如何将T转换为表示T是什么的字符串.

注意:我只是在玩耍,所以请不要担心什么时候需要这样的东西.

atz*_*tzz 66

没有内置的机制.typeid(T)::name()可以给出一些信息,但标准并没有要求这个字符串是人类可读的; 每种类型都有所不同.Microsoft Visual C++使用人类可读的字符串; 海湾合作委员会没有.

但是,您可以构建自己的系统.例如,基于特征.像这样的东西:

// default implementation
template <typename T>
struct TypeName
{
    static const char* Get()
    {
        return typeid(T).name();
    }
};

// a specialization for each type of those you want to support
// and don't like the string returned by typeid
template <>
struct TypeName<int>
{
    static const char* Get()
    {
        return "int";
    }
};

// usage:
const char* name = TypeName<MyType>::Get();
Run Code Online (Sandbox Code Playgroud)

  • 生成该特化可以说是宏的一种情况:`#define ENABLE_TYPENAME(A)template <> struct TypeName <A> {static const char*Get(){return #A; }};`.然后,当我编写我的类`Foo`时,我可以执行`ENABLE_TYPENAME(Foo)`,如果需要,将它放在正确的命名空间中. (19认同)
  • "对于每种类型都是不同的"不,你甚至没有这种保证 (9认同)
  • 请注意,GCC给出了Itanium ABI整齐的名称,可以使用Itanium ABI函数将其分解。 (2认同)

Ind*_*ant 19

对于海湾合作委员会,你必须使用一个技巧.使用cxxabi.h我为此编写了一个小包装器.

#include <string>
#include <iostream>
#include <iomanip>
#include <typeinfo>
#include <cxxabi.h>

#define DEBUG_TYPE(x) do { typedef void(*T)x; debug_type<T>(T(), #x); } while(0)

template<typename T>
struct debug_type
{
    template<typename U>
    debug_type(void(*)(U), const std::string& p_str)
    {
        std::string str(p_str.begin() + 1, p_str.end() - 1);
        std::cout << str << " => ";
        char * name = 0;
        int status;
        name = abi::__cxa_demangle(typeid(U).name(), 0, 0, &status);
        if (name != 0) { std::cout << name << std::endl; }
        else { std::cout << typeid(U).name() << std::endl; }
        free(name);
    }
};
Run Code Online (Sandbox Code Playgroud)

双括号是必要的.适用于任何类型.

现在你可以将它用于boost :: mpl:

DEBUG_TYPE((if_c<true, true_, false_>::type));
Run Code Online (Sandbox Code Playgroud)

将打印:

if_c<true, true_, false_>::type => bool_<true>
Run Code Online (Sandbox Code Playgroud)

  • @serup abi::__cxa_demanble 应该可以在任何架构上与 gcc 一起使用(例如我在 ARM 上使用过它)。 (2认同)

Mih*_*yan 7

string如果类型是基本类型之一,则不可能获取类型名称。对于用户定义的类型,您可以使用typeid(my_type).name(). 您还需要#include <typeinfo>:) 更多信息...


Jam*_*lis 6

你不能,至少不是直接的.将令牌或一系列令牌转换为字符串文字的唯一方法是在#宏内部使用预处理器的字符串化运算符().

如果你想获得一个表示类型的字符串文字,你必须自己编写一些东西,可能是通过使用宏来实例化模板并将其传递给字符串化的类型名称.

任何一般方法的一个问题是:应该为以下用途提供什么字符串:

Matrix<char> x;
typedef char MyChar;
Matrix<MyChar> y;
Run Code Online (Sandbox Code Playgroud)

两者xy是相同类型的,但是一个使用char直接和另一个使用的typedef MyChar.