developer tip

C ++에서 typename T를 문자열로 변환하는 방법

optionbox 2020. 12. 25. 09:38
반응형

C ++에서 typename T를 문자열로 변환하는 방법


이 질문에 이미 답변이 있습니다.

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

T를 T가 무엇인지 나타내는 문자열로 어떻게 변환합니까?

참고 : 나는 그냥 놀고 있기 때문에 언제 그런 것이 필요할지 걱정하지 마십시오.


이를위한 기본 제공 메커니즘이 없습니다. typeid(T)::name()정보를 제공 할 수 있지만 표준은이 문자열을 사람이 읽을 수 있도록 요구하지 않습니다. 각 유형에 따라 다릅니다. Microsoft Visual C ++는 사람이 읽을 수있는 문자열을 사용합니다. GCC는 그렇지 않습니다.

하지만 자신 만의 시스템을 구축 할 수 있습니다. 예를 들어, 특성 기반. 이 같은:

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

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:

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

will prints:

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

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.


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...


workaround way...

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

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

You could use a C++ reflection library. So:

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.


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

ReferenceURL : https://stackoverflow.com/questions/4484982/how-to-convert-typename-t-to-string-in-c

반응형