boost::typeindex::type_id<T>().pretty_name() 不是"pretty"
boost::typeindex::type_id<T>().pretty_name() is not "pretty"
我正在尝试在stdout上打印某个变量的类型。此代码:
std::string mystr {"dsadsadas"};
std::cout << boost::typeindex::type_id< decltype(mystr) >().pretty_name() << std::endl;
结果在:
std::__1::basic_string<char, std::__1::char_traits<char>, std::__1:: allocator<char> >
这绝对不好看。。为什么会发生这种情况?有什么变通办法吗??(注意,我正在使用c++14语义使用clang++进行编译(
我有一个名为cputil的库(在bitbucket上私人维护(,它有很多适用于c++11或更好版本的有用快捷方式。
其中一个概念是CCD_ 1。
其思想是,如果一个类有一个名为classname
的静态成员数据或函数,则它用于打印类的名称。如果没有,您可以提供一个提供类名的免费函数。如果不能做到这一点,typeid.name()
将被用作后备。
现在,你的类名可以随心所欲地漂亮。
在Coliru上直播
#include <iostream>
#include <type_traits>
/// static member of any type
namespace cpputil {
namespace detail {
template<class T>
constexpr auto has_static_member_classname(...)
-> std::false_type
{
return {};
}
template<class T>
constexpr auto has_static_member_classname(int)
-> decltype(T::classname, void(), std::true_type())
{
return {};
}
// static member of type function that returns anything but takes no args
template<class T>
constexpr auto has_static_function_classname(...)
-> std::false_type
{ return {}; }
template<class T>
constexpr auto has_static_function_classname(int)
-> decltype(T::classname(), void(), std::true_type())
{ return {}; }
}
// templated free function that takes no args, used as a fallback but may be overriden
template<class T> decltype(auto) classname() { return typeid(T).name(); }
namespace detail {
template<class T>
constexpr auto has_free_function_classname_0(...)
-> std::false_type
{ return {}; }
template<class T>
constexpr auto has_free_function_classname_0(int)
-> decltype(classname<T>(), void(), std::true_type())
{ return {}; }
// free function that takes a const ref
template<class T>
constexpr auto has_free_function_classname_1(...)
-> std::false_type
{ return {}; }
template<class T>
constexpr auto has_free_function_classname_1(int)
-> decltype(classname(std::declval<T>()), void(), std::true_type())
{ return {}; }
template<class T, typename = void>
struct classname_finder;
// highest priority - if there is a free function taking 1 parameter findable by ADL - use this
template<class T>
struct classname_finder<
T,
std::enable_if_t<
decltype(has_free_function_classname_1<T>(0))::value
>
>
{
static constexpr decltype(auto) apply() { return classname(*reinterpret_cast<const T*>(0)); }
static constexpr decltype(auto) apply(const T& t) { return classname(t); }
};
// priority 2 - if there is a static function, use that
template<class T>
struct classname_finder<
T,
std::enable_if_t<
decltype(has_static_function_classname<T>(0))::value &&
!decltype(has_free_function_classname_1<T>(0))::value
>
>
{
static constexpr decltype(auto) apply() { return T::classname(); }
static constexpr decltype(auto) apply(const T&) { return T::classname(); }
};
// priority 3 - if there is a static data member, use that
template<class T>
struct classname_finder<
T,
std::enable_if_t<
decltype(has_static_member_classname<T>(0))::value &&
!decltype(has_static_function_classname<T>(0))::value &&
!decltype(has_free_function_classname_1<T>(0))::value
>
>
{
static constexpr decltype(auto) apply() { return T::classname; }
static constexpr decltype(auto) apply(const T&) { return T::classname; }
};
// finally, use the cpputil::classname_of<X>() template overload
template<class T>
struct classname_finder<
T,
std::enable_if_t<
!decltype(has_static_member_classname<T>(0))::value &&
!decltype(has_static_function_classname<T>(0))::value &&
!decltype(has_free_function_classname_1<T>(0))::value &&
decltype(has_free_function_classname_0<T>(0))::value
>
>
{
static constexpr decltype(auto) apply() { return classname<T>(); }
static constexpr decltype(auto) apply(const T&) { return classname<T>(); }
};
}
template<class T>
auto classname_of(const T& t)
{
return detail::classname_finder<T>::apply(t);
}
template<class T>
auto classname_of()
{
return detail::classname_finder<T>::apply();
}
}
struct class_a
{
static const char* classname() { return "class_a"; }
};
struct class_b
{
constexpr static const char* classname = "class_b";
};
struct class_c
{
};
namespace cpputil {
template<> decltype(auto) classname<class_c>() { return "class_c"; }
}
struct class_d
{
};
decltype(auto) classname(const class_d&) { return "class_d"; }
struct class_e {
static const std::string& classname() { static const std::string _("class_e static function"); return _; }
};
static const char* classname(const class_e&) {
return "class_e free function should take priority";
}
// no classname decoration. should fall back to typeid() solution
struct class_f {
};
using namespace std;
auto main() -> int
{
class_a a;
class_b b;
class_c c;
class_d d;
class_e e;
class_f f;
cout << cpputil::classname_of(a) << endl;
cout << cpputil::classname_of(b) << endl;
cout << cpputil::classname_of(c) << endl;
cout << cpputil::classname_of(d) << endl;
cout << cpputil::classname_of(e) << endl;
cout << cpputil::classname_of(f) << endl;
cout << endl;
cout << cpputil::classname_of<class_a>() << endl;
cout << cpputil::classname_of<class_b>() << endl;
cout << cpputil::classname_of<class_c>() << endl;
cout << cpputil::classname_of<class_d>() << endl;
cout << cpputil::classname_of<class_e>() << endl;
cout << cpputil::classname_of<class_f>() << endl;
return 0;
}
打印
class_a
class_b
class_c
class_d
class_e free function should take priority
7class_f
class_a
class_b
class_c
class_d
class_e free function should take priority
7class_f
相关文章:
- 使用 [] 运算符时"binding reference of type discards qualifiers"
- 在 QVector<std::unique_ptr 上使用 std::find<Type>>
- 在类型和包装器之间reinterpret_cast是否安全<Type>?
- 使用 cmake 的 Linux 终端上的"Conversion to non-scalar type is requested"错误
- 控制到达非空函数clang(-Wreturn-type)的末尾
- std::unordered_map 类型对象声明期间出现"field has incomplete type"错误
- 将系数存储在头文件的数组中("does not name a type"错误)
- 尝试打开 ifstream 时出现"Incomplete type"错误
- 将成员函数作为构造函数参数调用时出错 "Variable is not a type name"
- 在"结构提升::enable_if<提升::is_pod<T>,无效>"中没有名为"type"的类型
- "Missing type specifier - int assumed"无法通过向主函数添加"return 0"来解决
- OpenCV CV_16F type
- C++ "错误:在'类 std::result_of< ... >"中没有名为'type'的类型"
- 将内存分配返回值强制转换为 TYPE 数组
- C++ 一个lambda浅拷贝const Type&如果它被赋予一个命名捕获,如[copy=val](){}?
- reference_wrapper导致"incomplete type is not allowed"
- 继承类时"invalid use of incomplete type ‘class tree_node_t’"
- 由于"error C4430: missing type specifier - int assumed. Note: C++ does not support default-int",我现在无法编
- 如何解决"'mutex' in namespace 'std' does not name a type"?
- 结构中的错误"Incomplete type is not allowed"