C++如何打印模板typename类型 封装boost numeric_cast报错怎么处理
问题原因
你判断的没错,报错的直接原因是Source和Target是模板类型参数,属于编译期的类型标记,不是可以直接参与字符串运算的变量。此外你原有代码还存在另一个隐藏问题:C++中不能直接对两个const char*类型的字符串字面量做+运算,+只会做指针算术,不会拼接字符串,需要先转成std::string类型再操作。
解决方案
方法1:使用typeid(兼容性最好,适合所有C++标准)
需要包含头文件<typeinfo>,通过typeid(类型).name()获取类型的名称字符串,缺点是不同编译器会对类型名做修饰(mangle),输出可读性一般,比如GCC下int会输出i,自定义类会输出带命名空间的修饰名。
修改后的代码示例:
#include <boost/numeric/conversion/cast.hpp> #include <stdexcept> #include <typeinfo> // 新增头文件 #include <string> // 新增头文件,用于字符串拼接 template <typename Source, typename Target> Target numeric_cast(Source src) { try { return boost::numeric_cast<Target>(src); // 补全对boost numeric_cast的调用 } catch(boost::numeric::bad_numeric_cast& e) { // 先把第一个字符串转成std::string再拼接,typeid获取类型名 throw std::runtime_error(std::string("numeric_cast failed, fromType: ") + typeid(Source).name() + " toType: " + typeid(Target).name()); } }
方法2:编译期获取可读类型名(适合C++17及以上)
如果需要干净无修饰的类型名,可以利用编译器内置的函数签名宏提取类型名,兼容性覆盖主流的GCC、Clang、MSVC编译器,输出可读性远高于typeid。
完整代码示例:
#include <boost/numeric/conversion/cast.hpp> #include <stdexcept> #include <string> #include <string_view> // 编译期获取类型名的工具函数 template <typename T> constexpr std::string_view get_type_name() { using namespace std::string_view_literals; #if defined(__clang__) || defined(__GNUC__) std::string_view func_sig = __PRETTY_FUNCTION__; constexpr auto prefix = "T = "sv; constexpr auto suffix = ";"sv; #elif defined(_MSC_VER) std::string_view func_sig = __FUNCSIG__; constexpr auto prefix = "get_type_name<"sv; constexpr auto suffix = ">("sv; #endif const auto pos_start = func_sig.find(prefix) + prefix.size(); const auto pos_end = func_sig.find(suffix, pos_start); return func_sig.substr(pos_start, pos_end - pos_start); } template <typename Source, typename Target> Target numeric_cast(Source src) { try { return boost::numeric_cast<Target>(src); } catch(boost::numeric::bad_numeric_cast& e) { throw std::runtime_error(std::string("numeric_cast failed, fromType: ") + get_type_name<Source>().data() + " toType: " + get_type_name<Target>().data()); } }
内容的提问来源于stack exchange,提问作者DonBaka
相关产品推荐
相关产品推荐

