如何为模板化FindTopItems函数设置默认谓词,替代重载函数?
如何仅保留模板版
FindTopItems并支持默认枚举参数调用 当然可以!咱们只需要给模板版本的谓词参数设置一个默认类型+默认值,同时把原非模板版本的枚举逻辑封装成适配的谓词结构,就能同时支持两种调用方式了。
具体实现步骤
- 先定义一个适配
ItemStatus的谓词结构体,把原非模板版本里的状态判断逻辑移进去:
#include <vector> #include <string> enum class ItemStatus { Initial, Active, Inactive }; // 封装枚举判断逻辑的谓词 struct StatusMatcher { ItemStatus target_status; // 构造函数默认用Initial,对应原函数的默认参数 explicit StatusMatcher(ItemStatus status = ItemStatus::Initial) : target_status(status) {} // 重载()运算符,实现原非模板版本的状态检查逻辑 bool operator()(int item) const { // 替换成你实际的状态判断逻辑,比如: // return GetItemStatus(item) == target_status; return true; // 示例代码,按需修改 } };
- 修改模板版
FindTopItems,给Predicate模板参数设置默认类型为StatusMatcher,同时给函数第二个参数设置默认值:
class YourClass { // 原函数带const修饰,所以假设属于某个类 public: template <typename Predicate = StatusMatcher> std::vector<int> FindTopItems(const std::string& query, const Predicate& predicate = StatusMatcher{}) const { // 你的函数核心逻辑在这里,和之前保持一致即可 return {}; } };
验证你的调用代码
现在你的main函数完全可以正常编译运行:
#include <string> using namespace std::literals; int main() { YourClass obj; obj.FindTopItems(""s, [](){ return true; }); /* 传lambda的谓词版本,自动推导类型 */ obj.FindTopItems(""s); /* 无第二个参数,自动使用默认的StatusMatcher(Initial) */ return 0; }
为什么这样可行?
- 当你不传第二个参数时,编译器会自动使用模板参数的默认值
StatusMatcher,同时调用函数的默认参数StatusMatcher{}(对应ItemStatus::Initial),完美复刻原非模板版本的默认行为。 - 当你传入lambda时,编译器会自动推导出
Predicate是lambda的类型,忽略默认类型,直接使用你传入的谓词。
可选优化:用lambda作为默认参数(更简洁)
如果你不想单独定义StatusMatcher结构体,也可以直接用lambda作为函数默认参数,不过需要借助std::function做类型推导:
#include <functional> class YourClass { public: template <typename Predicate = std::function<bool(int)>> std::vector<int> FindTopItems(const std::string& query, const Predicate& predicate = [](int item){ // 这里写原非模板版本的状态判断逻辑 return GetItemStatus(item) == ItemStatus::Initial; }) const { return {}; } };
不过这种方式会引入std::function的轻微性能开销,对性能敏感的场景,更推荐自定义结构体的方式。
内容的提问来源于stack exchange,提问作者Dmitry
相关产品推荐
相关产品推荐

