如何在 C++ 中将 typename T 转换为字符串
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4484982/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to convert typename T to string in c++
提问by Srikanth
While playing with templates in c++ I encountered a problem converting typename T to string. For example:
在 C++ 中使用模板时,我遇到了将 typename T 转换为字符串的问题。例如:
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;
}
How do I convert T to a string that says what T is.
如何将 T 转换为表示 T 是什么的字符串。
Note: I'm just playing around so please do not worry about when one might need such a thing.
注意:我只是在玩,所以请不要担心什么时候可能需要这样的东西。
回答by atzz
There is no built-in mechanizm for this. typeid(T)::name()
can give some info, but the standard does not mandate this string to be human-readable; just distinct for each type. Microsoft Visual C++ uses human-readable strings; GCC does not.
对此没有内置的机制。typeid(T)::name()
可以提供一些信息,但标准并没有要求这个字符串是人类可读的;只是每种类型不同。Microsoft Visual C++ 使用人类可读的字符串;海湾合作委员会没有。
You can build your own system, though. For example, traits-based. Something like this:
不过,您可以构建自己的系统。例如,基于特征。像这样的东西:
// 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();
回答by Industrial-antidepressant
For GCC you have to use a trick. Using cxxabi.h I wrote a little wrapper for this purpose.
对于 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);
}
};
Double parentheis is necessary. Works with any type.
双括号是必要的。适用于任何类型。
Now you can use it for boost::mpl:
现在您可以将它用于 boost::mpl:
DEBUG_TYPE((if_c<true, true_, false_>::type));
will prints:
将打印:
if_c<true, true_, false_>::type => bool_<true>
回答by James McNellis
You can't, at least not directly. The only way to convert a token or series of tokens into a string literal is using the preprocessor's stringization operator (#
) inside of a macro.
你不能,至少不能直接。将一个标记或一系列标记转换为字符串文字的唯一方法是在#
宏内部使用预处理器的字符串化运算符 ( )。
If you want to get a string literal representing the type, you'll have to write something yourself, perhaps by using a macro to instantiate the template and pass it the stringized type name.
如果你想得到一个表示类型的字符串文字,你必须自己编写一些东西,也许通过使用宏来实例化模板并将字符串化的类型名称传递给它。
One problem with any general approach is: what string should be given for the following uses:
任何通用方法的一个问题是:对于以下用途应该给出什么字符串:
Matrix<char> x;
typedef char MyChar;
Matrix<MyChar> y;
Both x
and y
are of the same type, but one uses char
directly and the other uses the typedef MyChar
.
两者x
和y
是相同类型的,但是一个使用char
直接和其他用途的typedef MyChar
。
回答by Mihran Hovsepyan
It is impossilbe to get name of type in string
if the type is one of base types. For user defined types you can use typeid(my_type).name()
. Also you need #include <typeinfo>
:)
more info...
string
如果类型是基本类型之一,则不可能获取类型名称。对于用户定义的类型,您可以使用typeid(my_type).name()
. 您还需要#include <typeinfo>
:)
更多信息...
回答by user3071398
workaround way...
解决方法...
#define Tprint(x) print<x>(#x)
template<typename T>
void print (string ltype){
cout<<ltype<<" = "<<sizeof(T)<<endl;
}
回答by Nick
You could use a C++ reflection library. So:
您可以使用C++ 反射库。所以:
using namespace ponder;
Class::declare<Matrix>();
std::string const& name = classByType<Matrix>().name();
This gives you other options as well once you have the metaclass information, like looking what the class members are.
一旦您获得元类信息,这也会为您提供其他选择,例如查看类成员是什么。
回答by Ajish Kb
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;
}
}
}