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

时间:2010-12-19 20:42:27

标签: 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;
}

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

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

7 个答案:

答案 0 :(得分:58)

此处没有内置机制。 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();

答案 1 :(得分:19)

对于GCC,你必须使用一个技巧。使用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);
    }
};

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

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

DEBUG_TYPE((if_c<true, true_, false_>::type));

会打印:

if_c<true, true_, false_>::type => bool_<true>

答案 2 :(得分:6)

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

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

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

Matrix<char> x;
typedef char MyChar;
Matrix<MyChar> y;

xy属于同一类型,但其中一个直接使用char,另一个使用typedef MyChar

答案 3 :(得分:2)

如果类型是基类型之一,则无法在string中获取类型名称。对于用户定义的类型,您可以使用typeid(my_type).name()。你还需要#include <typeinfo> :) more info...

答案 4 :(得分:2)

解决方法......

#define Tprint(x) print<x>(#x)

template<typename T>
void print (string ltype){
cout<<ltype<<" = "<<sizeof(T)<<endl;
}

答案 5 :(得分:0)

您可以使用C++ reflection library。所以:

using namespace ponder;

Class::declare<Matrix>();

std::string const& name = classByType<Matrix>().name();

一旦你掌握了元类信息,这也为你提供了其他选择,比如看看班级成员是什么。

答案 6 :(得分:-4)

template< typename From,typename To>
static inline bool superConvert(const From& fromVar,To& toVar)
{
    stringstream ss;
    ss<<fromVar;
    ss>>toVar;
    if(ss.fail())
    {
        return false;
    }
    else
    {
        From tempFrom;
        stringstream ss;
        ss<<toVar;
        ss>>tempFrom;
        if(tempFrom != fromVar)
        {
            return false;
        }
        else
        {
            return true;
        }
    }
}