C++泛型filter函数适配任意容器任意类型的实现问题求助
解决C++ filter函数支持任意容器的模板错误问题
问题背景
需要实现一个通用的filter函数,要求:
- 初始版本支持
std::list和std::function谓词,返回满足条件的新列表 - 改进1:支持任意元素类型的
std::list(已完成) - 改进2:支持任意类型的容器(实现时遇到编译错误)
初始改进后的可运行代码:
#include <iostream> #include <list> #include <functional> template <typename T> std::list<T> filter (std::list<T>& l, std::function<bool(T)> p){ for (auto it = l.begin(); it != l.end(); ++it){ if (p(*it)){ continue; } else { it = l.erase(it); } } return l; } int main() { std::list<int> initial_list; for (int i = 0; i <= 50; ++i){ initial_list.push_back(i); } std::function<bool(int)> predicate = [](const int& a){ return a % 2 == 0; }; std::list<int> end_list = filter(initial_list, predicate); for (auto e : end_list){ std::cout << e << " "; } std::cout << std::endl; return 0; }
尝试支持任意容器时的错误代码:
template <typename T, typename U> T<U> filter (T<U>& l, std::function<bool(U)> p){ for (auto it = l.begin(); it != l.end(); ++it){ if (p(*it)){ continue; } else { it = l.erase(it); } } return l; }
编译错误信息:
problem5.cpp:6:1: error: ‘T’ is not a template T<U> filter (T<U>& l, std::function<bool(U)> p){ ^ problem5.cpp:6:14: error: ‘T’ is not a template T<U> filter (T<U>& l, std::function<bool(U)> p){ ^
错误原因
原模板参数声明template <typename T, typename U>中,T被当作普通类型而非模板类型,但实际使用时T是容器模板(如std::list、std::vector),需要用模板模板参数来声明这种模板类型的参数。
另外原代码存在逻辑问题:直接在输入容器上调用erase修改了原容器,不符合filter函数“返回新容器、不修改原数据”的语义。
正确实现方案
1. 修正模板参数
使用模板模板参数声明容器类型,同时用通用的谓词类型替代std::function以提升性能。
2. 重构逻辑:创建新容器返回
遍历原容器,将满足谓词的元素插入新容器,避免修改原容器。
完整代码:
#include <iostream> #include <list> #include <vector> #include <functional> // 支持任意容器的通用filter函数 template <template <typename...> typename Container, typename T, typename Predicate> Container<T> filter(const Container<T>& input_container, Predicate predicate) { Container<T> result; for (const auto& elem : input_container) { if (predicate(elem)) { result.push_back(elem); } } return result; } int main() { // 测试std::list std::list<int> int_list; for (int i = 0; i <= 20; ++i) { int_list.push_back(i); } auto even_list = filter(int_list, [](int num) { return num % 2 == 0; }); std::cout << "过滤后的std::list(偶数):"; for (int num : even_list) { std::cout << num << " "; } std::cout << "\n"; // 测试std::vector std::vector<std::string> str_vec = {"apple", "banana", "cherry", "date", "elderberry"}; auto long_str_vec = filter(str_vec, [](const std::string& str) { return str.size() >= 6; }); std::cout << "过滤后的std::vector(长度≥6的字符串):"; for (const auto& str : long_str_vec) { std::cout << str << " "; } std::cout << "\n"; return 0; }
关键说明
- 模板模板参数:
template <typename...> typename Container声明Container是一个接受任意数量模板参数的容器模板,适配std::list、std::vector等标准容器。 - 通用谓词:使用
typename Predicate作为谓词参数,支持lambda、函数指针、函数对象等任意可调用类型,比std::function更高效(避免类型擦除开销)。 - 无副作用:创建新容器存储结果,原输入容器保持不变,符合函数式编程中filter的预期行为。
内容的提问来源于stack exchange,提问作者fluxstark
相关产品推荐
相关产品推荐

