1

For debugging purposes (on a Linux platform using g++4.6 in c++11 mode) I wanted to know the exact type with which a template was instantiated. A similar thing was discussed earlier: Print template typename at compile time and How to convert typename T to string in c++, but I wans't happy with the solution. I came up with the following code:

#include <typeinfo>
#include <type_traits>
#include <string>

template<typename FIRST> std::string typeName() {

    std::string tName;

    // get name of the type (and remove the '\n' at the end)
    FILE *fp = popen((std::string("c++filt -t ") + std::string(typeid(FIRST).name())).c_str(), "r");
    char buf[1024]; fgets(buf, 1024, fp); fclose(fp);
    tName += buf; tName.erase(std::prev(tName.end()));

    // check whether we have a const qualifier
    if(std::is_const<FIRST>::value) { tName += " const"; }

    // check whether type declares a volatile variable
    if(std::is_volatile<FIRST>::value) { tName += " volatile"; }

    // check for lvalue and rvalue references
    if(std::is_lvalue_reference<FIRST>::value) { tName += "&"; }
    if(std::is_rvalue_reference<FIRST>::value) { tName += "&&"; }

    return tName;
}

template<typename FIRST, typename SECOND, typename... OTHER> std::string typeName() {
    return typeName<FIRST>() + ", " + typeName<SECOND, OTHER...>();
}


#include <iostream>

int main() {

    std::cout << typeName<std::string*&, int&&, char const* const>() << std::endl;

    return 0;
}

When compiled by

g++ -std=gnu++0x -o test test.cpp

it prints

std::basic_string<char, std::char_traits<char>, std::allocator<char> >*&, int&&, char const* const

Basically I am pretty happy with the output but the way I get the demangeled typename via a call of c++filt is imho quite nasty. Do you see another way to achieve the same output?

Thank you for any hints!

Community
  • 1
  • 1
mg84
  • 287
  • 2
  • 9

0 Answers0