如何编写可同时兼容std::array和std::vector的模板函数
问题解答
错误原因
你原有代码编译失败的核心原因是:std::array的长度是编译期确定的非类型模板参数,S::size()是运行期才能调用的成员函数,无法在模板参数推导的编译阶段作为常量值使用,所以匹配std::array实例的逻辑存在问题。
实现方案
完全可以实现同时接收std::vector和std::array的模板函数,这里给出两种常用实现方式:
方案1:兼容C++11及以上版本
通过自定义类型萃取判断容器类型,不需要获取std::array的具体长度,仅匹配模板结构即可:
#include <string> #include <sstream> #include <vector> #include <array> #include <type_traits> // 类型萃取:判断是否为std::vector实例 template<typename T> struct is_vector : std::false_type {}; template<typename T, typename Alloc> struct is_vector<std::vector<T, Alloc>> : std::true_type {}; // 类型萃取:判断是否为std::array实例 template<typename T> struct is_array : std::false_type {}; template<typename T, size_t N> struct is_array<std::array<T, N>> : std::true_type {}; template <typename S, typename = std::enable_if_t< is_vector<S>::value || is_array<S>::value>> std::string arr2String(const S& seqContainer) { std::stringstream res; for (const auto& element : seqContainer) { res << element << "|"; } return res.str(); }
方案2:C++20及以上版本简化写法
用C++20引入的concept约束模板参数,代码更简洁易读:
#include <string> #include <sstream> #include <vector> #include <array> #include <type_traits> template<typename T> struct is_vector : std::false_type {}; template<typename T, typename Alloc> struct is_vector<std::vector<T, Alloc>> : std::true_type {}; template<typename T> struct is_array : std::false_type {}; template<typename T, size_t N> struct is_array<std::array<T, N>> : std::true_type {}; // 定义约束:仅允许std::vector或std::array类型传入 template<typename S> concept VectorOrArray = is_vector<S>::value || is_array<S>::value; template <VectorOrArray S> std::string arr2String(const S& seqContainer) { std::stringstream res; for (const auto& element : seqContainer) { res << element << "|"; } return res.str(); }
测试示例
#include <iostream> int main() { std::vector<int> vec = {1,2,3,4}; std::array<std::string, 3> arr = {"test1", "test2", "test3"}; std::cout << arr2String(vec) << "\n"; // 输出:1|2|3|4| std::cout << arr2String(arr) << "\n"; // 输出:test1|test2|test3| return 0; }
可选优化
如果不需要末尾多余的|,可以在遍历结束后删除最后一个字符,或者遍历过程中判断是否为首个元素调整分隔符输出逻辑即可。
内容的提问来源于stack exchange,提问作者Yves
相关产品推荐
相关产品推荐

