Can I create templates for types OR non-types?

I use a lot of templates, and sometimes itโ€™s hard for me to figure out what type it really is. I wanted to write a utility to give me a pretty, pretty string name for each type - typeid () just doesn't cut. For example, if I have only vector<int> , gcc.4.6.4 in my field creates the following with a type:

 St6vectorIiSaIiEE 

ideally want

 std::vector< int, std::allocator< int > > 

I wrote something that will work with any type or pattern by type, but just provide two patterns:

 template <typename T> struct simple_type_name; template <template <typename....> class T> struct template_type_name; 

Which, when specializing in int or std::vector , can help me create the strings I want. I also have a partial specialization simple_type_name only on any Base<Args...> , to go through all the arguments and do everything as needed. This is great for int and vector<int> and indeed any arbitrarily complex template material ... as long as all templates are types.

If this helps, my version of the โ€œfull templateโ€ looks like this:

 template <template <typename...> class Base, typename... Args> struct simple_type_name<Base<Args...>> { static std::string name(int indent = 0) { std::string base = template_type_name<Base>::name(indent); std::string args[] = { simple_type_name<Args>::name(indent + 4)... } ; // basic string putting together stuff here that is less interesting } }; 

Question : how can I do what I work for, say, std::array<int, 10> ? I do not know how to handle parameters other than type. Is it possible?

+8
c ++ c ++ 11 templates
source share
2 answers

A slightly simpler version of demangle with some demangle wrappers:

 #include <string> #include <memory> #include <typeinfo> #include <cxxabi.h> std::string demangle( const char* symbol ) { const std::unique_ptr< char, decltype( &std::free ) > demangled( abi::__cxa_demangle( symbol, 0, 0, 0 ), &std::free ); return demangled ? demangled : symbol; } std::string demangle( const std::string& symbol ) { return demangle( symbol.c_str() ); } std::string demangle( const std::type_info& ti ) { return demangle( ti.name() ); } 

which allows you to use:

 std::cout << demangle( typeid( T ) ) << std::endl; 

to see what T really is.

+3
source share

If you like to have a specific g ++ demang:

 #include <iostream> #include <typeinfo> #include <cxxabi.h> std::string demangle(const std::string& source_name) { std::string result; size_t size = 4096; // __cxa_demangle may realloc() char* name = static_cast<char*>(malloc(size)); try { int status; char* demangle = abi::__cxa_demangle(source_name.c_str(), name, &size, &status); if(demangle) result = demangle; else result = source_name; } catch(...) {} free(name); return result; } template <typename T, int I> struct X {}; int main() { // Prints: X<int, 0> std::cout << demangle(typeid(X<int, 0>).name()) << std::endl; } 

(Added try / catch - thanks to Daniel Freyu)

+7
source share

All Articles