如何将typename T转换为C ++中的string

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

template <typename T> class Matrix { public: Matrix() { //my_type = string type of T. ie if T is char. I want my_type to be "char". } string my_type; } 

如何将T转换为表示T是什么的string。

注:我只是在玩耍,所以请不要担心什么时候可能需要这样的事情。

这里没有内置的机制。 typeid(T)::name()可以给出一些信息,但是标准并没有要求这个string是可读的; 只是每种types都不同。 Microsoft Visual C ++使用人类可读的string; GCC没有。

不过,你可以build立你自己的系统。 例如,基于特质的。 像这样的东西:

 // 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(); 

对于海湾合作委员会,你必须使用一个技巧。 使用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); } }; 

双父项是必要的。 适用于任何types。

现在你可以使用boost :: mpl:

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

将打印:

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

你不能,至less不能直接。 将令牌或一系列令牌转换为string文本的唯一方法是使用macros内的预处理器的string化运算符( # )。

如果你想得到一个表示types的string,你必须自己写一些东西,也许通过使用一个macros来实例化这个模板,并把它传递给stringtypes的名字。

任何一般方法的一个问题是:应该给以下用途的string:

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

xy都是相同的types,但是一个直接使用char ,另一个使用typedef MyChar

解决方法…

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

如果types是基types之一,则不可能获得string的types名称。 对于用户定义的types,可以使用typeid(my_type).name() 。 你也需要#include <typeinfo> 🙂 更多信息…

你可以使用C ++reflection库 。 所以:

 using namespace ponder; Class::declare<Matrix>(); std::string const& name = classByType<Matrix>().name(); 

一旦获得了元类的信息,就可以为你提供其他的select,比如查看类的成员。

 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; } } }