如何在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 15:31:18  来源:igfitidea点击:

How to convert typename T to string in c++

c++templates

提问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 xand yare of the same type, but one uses chardirectly and the other uses the typedef MyChar.

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

回答by Mihran Hovsepyan

It is impossilbe to get name of type in stringif 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;
        }
    }
}