如何在C++中实现两个谓词函数的逻辑与组合?
当然可以实现这个功能!
完全没问题,用C++的lambda表达式就能轻松实现两个谓词的逻辑与组合,下面是具体的实现方案:
基础实现(匹配你定义的Predicate类型)
我们可以直接在andPredicate函数里返回一个lambda,捕获传入的两个谓词,调用时返回它们的逻辑与结果:
#include <functional> template <typename T> using Predicate = std::function<bool(T const&)>; template <typename T> static Predicate<T> andPredicate(Predicate<T> a, Predicate<T> b) { // 捕获两个谓词,返回组合后的新谓词 return [a, b](const T& val) { // 和原生&&一样支持短路求值:第一个谓词为false时不会调用第二个 return a(val) && b(val); }; }
测试示例
按照你给出的预期行为,我们可以写一段测试代码验证功能:
#include <iostream> int main() { Predicate<int> a = [](int num) { return num < 5; }; Predicate<int> b = [](int num) { return num > 0; }; Predicate<int> c = andPredicate(a, b); int number = 3; bool result = c(number); // 结果为true,3满足0<3<5 std::cout << std::boolalpha << result << std::endl; // 输出true number = 6; result = c(number); // 结果为false,6不小于5 std::cout << std::boolalpha << result << std::endl; // 输出false number = -2; result = c(number); // 结果为false,-2不大于0 std::cout << std::boolalpha << result << std::endl; // 输出false return 0; }
优化小技巧
如果担心std::function的拷贝开销,可以用移动捕获来优化,避免不必要的拷贝操作:
template <typename T> static Predicate<T> andPredicate(Predicate<T> a, Predicate<T> b) { return [a = std::move(a), b = std::move(b)](const T& val) { return a(val) && b(val); }; }
更泛型的扩展(不依赖std::function)
如果你不需要统一的Predicate<T>类型,还可以实现一个更泛型的版本,支持任意可调用对象(比如lambda、函数指针、自定义functor),避免std::function的类型擦除开销:
template <typename T, typename Pred1, typename Pred2> auto andPredicate(Pred1 a, Pred2 b) { return [a, b](const T& val) { return a(val) && b(val); }; } // 使用方式(不需要显式指定Predicate类型) int main() { auto a = [](int num) { return num < 5; }; auto b = [](int num) { return num > 0; }; auto c = andPredicate<int>(a, b); bool result = c(3); // true return 0; }
这种方式性能更优,因为没有std::function的运行时开销,不过返回的是编译器生成的闭包类型,无法直接统一到Predicate<T>(如果需要统一类型,再把它包装进std::function即可)。
内容的提问来源于stack exchange,提问作者t4dohx
相关产品推荐
相关产品推荐

