打印c++类型信息

nxdong August 10, 2022 [cpp] #cpp

打印类型信息

代码

type_test.cpp 内容如下:

#include <stdint.h>
#include <iostream>
#include <typeinfo>
#include <memory>
#include <cxxabi.h>
#include <type_traits>
#include <string>

std::string demangle(const char *name)
{

    int status = -4; // some arbitrary value to eliminate the compiler warning

    // enable c++11 by passing the flag -std=c++11 to g++
    std::unique_ptr<char, void (*)(void *)> res{
        abi::__cxa_demangle(name, NULL, NULL, &status),
        std::free};

    return (status == 0) ? res.get() : name;
}

struct MyStruct
{
    int a;
    char b;
};

int foo(int a, std::string b)
{
    return 42;
}

template <typename T, typename Enable = void>
class Point
{
public:
    T height()
    {

        std::cout << "无效的类型,这个应该在构造的时候就拒绝" << std::endl;
        return T{};
    }
};

template <typename T>
class Point<T, typename std::enable_if<std::is_arithmetic<T>::value>::type>
{
private:
    T x;
    T y;

public:
    T width()
    {
        return x;
    }
    T height()
    {
        return y;
    }
};

int main(int argc, char const *argv[])
{
    std::cout << "type id - MyStruct type    : " << demangle(typeid(MyStruct).name()) << std::endl;
    struct MyStruct mys;
    std::cout << "type id - MyStruct Object  : " << demangle(typeid(mys).name()) << std::endl;
    std::cout << "type id - MyStruct Pointer : " << demangle(typeid(&mys).name()) << std::endl;
    std::cout << "type id - function demangle: " << demangle(typeid(demangle).name()) << std::endl;
    std::cout << "type id - function foo     : " << demangle(typeid(foo).name()) << std::endl;

    Point<int> a;
    std::cout << "type id - template class point            : " << demangle(typeid(Point<int>).name()) << std::endl;
    std::cout << "type id - template class object           : " << demangle(typeid(a).name()) << std::endl;
    std::cout << "type id - template class object pointer   : " << demangle(typeid(&a).name()) << std::endl;
    std::cout << "type id - template class object func ret  : " << demangle(typeid(a.height()).name()) << std::endl;
    Point<float> b;
    std::cout << "type id - template class point<float>             : " << demangle(typeid(Point<int>).name()) << std::endl;
    std::cout << "type id - template class object<float>            : " << demangle(typeid(b).name()) << std::endl;
    std::cout << "type id - template class object pointer<float>    : " << demangle(typeid(&b).name()) << std::endl;
    std::cout << "type id - template class object func ret<float>   : " << demangle(typeid(b.height()).name()) << std::endl;
    Point<struct MyStruct> c;
    std::cout << "type id - template class point<MyStruct>              : " << demangle(typeid(Point<struct MyStruct>).name()) << std::endl;
    std::cout << "type id - template class object<MyStruct>             : " << demangle(typeid(c).name()) << std::endl;
    std::cout << "type id - template class object pointer<MyStruct>     : " << demangle(typeid(&c).name()) << std::endl;
    std::cout << "type id - template class object func ret<MyStruct>    : " << demangle(typeid(c.height()).name()) << std::endl;
    c.height();
    return 0;
}

编译&&运行

g++ type_test.cpp -std=c++17

./a.out 
type id - MyStruct type    : MyStruct
type id - MyStruct Object  : MyStruct
type id - MyStruct Pointer : MyStruct*
type id - function demangle: std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > (char const*)
type id - function foo     : int (int, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)
type id - template class point            : Point<int, void>
type id - template class object           : Point<int, void>
type id - template class object pointer   : Point<int, void>*
type id - template class object func ret  : int
type id - template class point<float>             : Point<int, void>
type id - template class object<float>            : Point<float, void>
type id - template class object pointer<float>    : Point<float, void>*
type id - template class object func ret<float>   : float
type id - template class point<MyStruct>              : Point<MyStruct, void>
type id - template class object<MyStruct>             : Point<MyStruct, void>
type id - template class object pointer<MyStruct>     : Point<MyStruct, void>*
type id - template class object func ret<MyStruct>    : MyStruct
无效的类型,这个应该在构造的时候就拒绝

参考

unmangling-the-result-of-stdtype-infoname