C++可变参数模板如何接收不同类型的ColumnValue实例并正确打印值
错误原因
你遇到的编译错误本质是不同模板参数实例化的ColumnValue是完全独立的类型,C++要求std::initializer_list的所有元素必须是相同类型,因此你尝试将不同类型的ColumnValue放入{args...}构造初始化列表时类型冲突,编译失败。
解决方案
方案1:C++17及以上版本(折叠表达式实现,代码最简洁)
利用C++17引入的折叠表达式特性,无需构造统一类型的容器即可展开参数包,同时可以根据不同Value类型执行对应操作:
#include <iostream> #include <string> template <typename Value> struct ColumnValue { std::string columnName; Value value; }; // 不同类型的自定义处理逻辑 template<typename T> void process_value(const T& val) { std::cout << val << '\n'; } template<> void process_value(const std::string& val) { std::cout << "\"" << val << "\"\n"; } template <template<typename> typename ...ColType, typename ...ValType> void print(const ColType<ValType>& ...args) { // 折叠表达式展开逐个处理参数 (process_value(args.value), ...); } int main() { ColumnValue<int> v{ .columnName="hello", .value=222 }; ColumnValue<std::string> d{ .columnName="hello", .value="hellooooo" }; print(v, d); return 0; }
运行后输出完全符合预期:
222 "hellooooo"
方案2:C++11兼容版本(递归展开参数包)
如果需要兼容更低版本的C++标准,可以采用递归的方式逐个处理可变参数包:
#include <iostream> #include <string> template <typename Value> struct ColumnValue { std::string columnName; Value value; }; // 不同类型的自定义处理逻辑 template<typename T> void process_value(const T& val) { std::cout << val << '\n'; } template<> void process_value(const std::string& val) { std::cout << "\"" << val << "\"\n"; } // 递归终止函数 void print() {} template <typename T, typename ...Args> void print(const ColumnValue<T>& first, const Args& ...rest) { process_value(first.value); print(rest...); } int main() { ColumnValue<int> v{ .columnName="hello", .value=222 }; ColumnValue<std::string> d{ .columnName="hello", .value="hellooooo" }; print(v, d); return 0; }
两种方案都支持传入任意数量、任意模板参数的ColumnValue对象,且可以通过扩展process_value的重载/特化实现不同类型的自定义操作。
内容的提问来源于stack exchange,提问作者Luke Xu
相关产品推荐
相关产品推荐

