C++11で型の名前を出す方法

2014年9月21日日曜日

プログラム

t f B! P L
さて、templateなんかが一杯くっつき始めると、
_Tpなんて出てくる型が何の型かさっぱり……
となってしまいます。

便利な型名のダンプルーチンがPrint variable type in C++にあったので引用。
#include <type_traits>
#include <typeinfo>
#ifndef _MSC_VER
#   include <cxxabi.h>
#endif
#include <memory>
#include <string>
#include <cstdlib>

template <class T>
std::string
type_name()
{
    typedef typename std::remove_reference<T>::type TR;
    std::unique_ptr<char, void(*)(void*)> own
           (
#ifndef _MSC_VER
                abi::__cxa_demangle(typeid(TR).name(), nullptr,
                                           nullptr, nullptr),
#else
                nullptr,
#endif
                std::free
           );
    std::string r = own != nullptr ? own.get() : typeid(TR).name();
    if (std::is_const<TR>::value)
        r += " const";
    if (std::is_volatile<TR>::value)
        r += " volatile";
    if (std::is_lvalue_reference<T>::value)
        r += "&";
    else if (std::is_rvalue_reference<T>::value)
        r += "&&";
    return r;
}
これを、type_name.hなんてファイルにしておいて、
#include <type_name.h>
...
  std::cout << "type " << type_name<_Tp>() << std::endl;
なんてするだけで型名がダンプできて便利。変数に対してやるときは、
...type_name<decltype(a)>()...
と使います。

以下に実例追記



typeid(i).name()との比較で示すと、末尾のTPを動かすと、こう出力されます。
### int ###
typeid.name: i, type_name: int

### const int ###
typeid.name: i, type_name: int const

### std::string ###
typeid.name: Ss, type_name: std::string

### const std::string& ###
typeid.name: Ss, type_name: std::string const&

### const std::string&& ###
typeid.name: Ss, type_name: std::string const&&

とても便利。これ大事


以下、TPのソースです。
#include <iostream>
#include "type_name.h"

main()
{
    int i = 1;
    std::cout << "### int ###" << std::endl;
    std::cout << "typeid.name: " << typeid(i).name()
    << ", type_name: " << type_name<decltype(i)>() << std::endl << std::endl;
    const int ci = 1;
    std::cout << "### const int ###" << std::endl;
    std::cout << "typeid.name: " << typeid(ci).name()
    << ", type_name: " << type_name<decltype(ci)>() << std::endl << std::endl;
    std::string s = "hello";
    std::cout << "### std::string ###" << std::endl;
    std::cout << "typeid.name: " << typeid(s).name()
    << ", type_name: " << type_name<decltype(s)>() << std::endl << std::endl;
    const std::string& csr = s;
    std::cout << "### const std::string& ###" << std::endl;
    std::cout << "typeid.name: " << typeid(csr).name()
    << ", type_name: " << type_name<decltype(csr)>() << std::endl << std::endl;
    const std::string&& csrr = std::string("test");
    std::cout << "### const std::string&& ###" << std::endl;
    std::cout << "typeid.name: " << typeid(csrr).name()
    << ", type_name: " << type_name<decltype(csrr)>() << std::endl << std::endl;
}
便利、便利

ラベル

AndroidTV (1) chromebook (2) DIY (4) docker (1) git (4) Ingress (4) llvm (3) MacBook (1) MVNO (1) narou (1) PS4 (2) QNAPNAS (9) SIMD (9) SmartBand (8) Ubuntu (9) VAIO (1) Windows (2) wsl (2) wsl2 (1) Xperia (20) トルネ (3) プログラム (26) ルーター (18) 音楽 (6) 家事 (2) 自炊 (2) 電子書籍 (2) 洋食 (4)

フォロワー

QooQ