我使用了很多模板,偶尔很难弄清楚究竟是什么类型的。我想编写一个实用程序,为每个类型提供一个漂亮,漂亮的字符串名称 - typeid()只是不切割它。例如,如果我只有vector<int>
,我的框上的gcc.4.6.4会生成以下带有typeid的内容:
St6vectorIiSaIiEE
虽然我理想地想要
std::vector<
int,
std::allocator<
int
>
>
我写了一些可以在类型上使用任何类型或模板的东西,但只提供了两个模板:
template <typename T> struct simple_type_name;
template <template <typename....> class T> struct template_type_name;
当专注于int
或std::vector
时,可以帮助我构建我想要的字符串。我对simple_type_name
的任何Base<Args...>
都有部分专业化,可以遍历所有的args,并在适当的时候做所有事情。这对于int
和vector<int>
以及任何任意复杂的模板内容都是完全正常的......只要所有模板都是类型。
如果有帮助,我的“完整模板”版本如下所示:
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
}
};
问题:如何制作我的作品,比如std::array<int, 10>
?我不知道如何处理非类型参数。这甚至可能吗?
答案 0 :(得分:7)
如果你想要一个特定于g ++的demangle:
#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;
}
(添加了试试/捕获 - 感谢Daniel Frey)
答案 1 :(得分:3)
更简单的demangle
版本,带有一些便利包装:
#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() );
}
允许您使用:
std::cout << demangle( typeid( T ) ) << std::endl;
直接查看T
实际上是什么。