开发者

How to convert typename T to string in c++ [duplicate]

This question already has answers here: Is it possible to print a variable's type in standard C++? (25 answers) Closed 5 years ago.

While playing with templates in c++ I encountered a problem converting typename T to string. For example:

template <typename T>
class Matrix {
   public:
        Matrix() {
           //my_type = string type of T. i.e.开发者_如何学C 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.

Note: I'm just playing around so please do not worry about when one might need such a thing.


There is no built-in mechanism for this.

typeid(T)::name() can give some info, but the standard does not mandate this string to be human-readable; just that it has to be distinct for each type. (E.x. Microsoft Visual C++ uses human-readable strings; GCC does not.)

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


For GCC you have to use a trick. Using cxxabi.h, I wrote a little wrapper for this purpose:

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

The double parentheses are necessary. Will work with any type.

Now you can use it for boost::mpl:

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

will print:

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜