如何将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;
x
和y
都是相同的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; } } }