使用C++模板实现HTTP统一返回Message类的类型转换错误求助
问题原因
编译报错的核心是:typeid属于运行时类型判断,编译器在编译模板类的toJson函数时,所有分支的代码都会被尝试编译,不管运行时会不会走到该分支。比如当T是std::string时,intToJson("data", data)这行代码里的data是string类型,无法转换为int,直接触发编译错误。
解决方法
方法一:模板特化(兼容C++11及以上)
针对不同的T类型,特化Message类的toJson函数,让不同类型对应独立的实现:
// 基础模板声明 template<typename T> class Message { public: Message(int c, const std::string& m, const T& d) : code(c), msg(m), data(d) {} void toJson(); private: T data; int code; std::string msg; }; // 特化int类型的toJson template<> void Message<int>::toJson() { intToJson("code", code); stringToJson("message", msg); intToJson("data", data); } // 特化string类型的toJson template<> void Message<std::string>::toJson() { intToJson("code", code); stringToJson("message", msg); stringToJson("data", data); } // 特化JsonBase派生类的toJson template<> void Message<JsonBase>::toJson() { intToJson("code", code); stringToJson("message", msg); classToJson("data", data); }
每个类型的toJson独立编译,不会出现类型不匹配问题。
方法二:函数重载(兼容C++11及以上)
把数据转JSON的逻辑封装成重载函数,让编译器自动匹配正确版本,无需运行时判断:
// 重载不同类型的转JSON函数 bool toJsonData(const std::string& key, int value) { return intToJson(key, value); } bool toJsonData(const std::string& key, const std::string& value) { return stringToJson(key, value); } bool toJsonData(const std::string& key, const JsonBase& value) { return classToJson(key, value); } // 模板类的toJson简化实现 template<typename T> void Message<T>::toJson() { intToJson("code", code); stringToJson("message", msg); // 编译器自动匹配对应的重载函数 toJsonData("data", data); }
新增类型时只需添加对应的toJsonData重载,无需修改Message类代码。
方法三:if constexpr(C++17及以上)
利用C++17的编译时条件判断if constexpr,不符合条件的分支会被编译器完全忽略,不参与编译:
#include <type_traits> // 需要包含头文件 template<typename T> void Message<T>::toJson() { intToJson("code", code); stringToJson("message", msg); if constexpr (std::is_same_v<T, int>) { intToJson("data", data); } else if constexpr (std::is_same_v<T, std::string>) { stringToJson("data", data); } else if constexpr (std::is_base_of_v<JsonBase, T>) { classToJson("data", data); } }
保留原代码的分支结构,同时通过编译时判断避免无效代码的编译,逻辑更直观。
内容的提问来源于stack exchange,提问作者郭苏莹
相关产品推荐
相关产品推荐

