C++:如何复用返回值不同、行为略有差异的函数代码?
解决方案:用模板+收集器模式消除代码冗余
核心思路是将业务逻辑与结果收集逻辑解耦,通过模板参数传递不同的"收集器"对象,让同一套核心逻辑可以适配不同的输出需求(生成容器、计数、判断是否有元素等)。
实现步骤
1. 提取核心业务逻辑到模板函数
把原来重复的循环、条件判断等核心逻辑抽出来,写成一个模板函数,模板参数接收一个"收集器",所有需要添加元素的操作都委托给收集器处理:
#include <vector> template<typename Collector> auto processCore(int& a, int& b, int& c, Collector&& collector) { // 这里是你的复杂核心逻辑,只写一次 for(int i=0;i<10;i++){ if(a - b > 0){ // 不再直接操作容器/计数器,而是调用收集器的add方法 collector.add(c); } else if (c == 1){ // 提前返回时,获取收集器的当前结果 return collector.getResult(); } else continue; } return collector.getResult(); }
2. 定义不同的收集器类
根据不同的需求,实现对应的收集器,每个收集器只负责自己的结果收集逻辑:
// 收集器1:生成vector容器 class VectorCollector { private: std::vector<int> data; public: void add(int val) { data.emplace_back(val); } // 返回最终结果,用move避免拷贝 std::vector<int> getResult() { return std::move(data); } }; // 收集器2:统计元素数量 class CountCollector { private: int count = 0; public: // 参数仅为兼容接口,实际不需要使用 void add(int) { count++; } int getResult() { return count; } }; // 收集器3:仅判断是否有元素(比计数更高效) class ExistsCollector { private: bool hasElement = false; public: void add(int) { hasElement = true; } bool getResult() { return hasElement; } };
3. 封装对外接口
原来的getData、getSize等函数现在只需要调用模板函数并传入对应的收集器,代码极度简洁:
// 原有的生成容器接口 std::vector<int> getData(int& a, int& b, int& c) { return processCore(a, b, c, VectorCollector{}); } // 获取元素数量的接口 int getSize(int& a, int& b, int& c) { return processCore(a, b, c, CountCollector{}); } // 判断是否有元素的接口(替代empty(),无需创建容器) bool hasData(int& a, int& b, int& c) { return processCore(a, b, c, ExistsCollector{}); }
优势说明
- 消除冗余:核心逻辑只维护一次,避免了多份代码同步更新的风险
- 编译期高效:模板参数是编译期决议,没有运行时多态的开销
- 扩展性强:如果需要新增其他需求(比如统计元素和、过滤特定元素),只需要新增对应的收集器类,完全不需要修改核心逻辑
- 语义清晰:每个收集器职责单一,代码可读性更高
内容的提问来源于stack exchange,提问作者mr__orangee
相关产品推荐
相关产品推荐

