返回

STL 中的仿函数与谓词:超越函数调用的力量

Android

引言

在 C++ 标准模板库 (STL) 的广阔世界中,仿函数和谓词脱颖而出,它们提供了一种独特的范式,可以将功能代码整齐地封装成轻量级对象。仿函数通过重载括号运算符 (),将自己伪装成函数,而谓词则专注于返回布尔值。本指南将深入探究这些概念,阐明它们的区别并展示如何在 NDK 中有效利用它们。

仿函数:函数对象的伪装

仿函数是轻量级的对象,具有函数的所有功能。通过重载括号运算符,它们允许以函数调用的方式调用。与函数不同,仿函数是按值传递的,这意味着算法不会改变原始仿函数的状态。这确保了仿函数的并发性和可重用性。

例如,考虑一个计算两个数字之和的仿函数:

struct Summator {
  int operator()(int a, int b) {
    return a + b;
  }
};

使用这种仿函数,我们可以使用函数调用的语法对两个数字求和:

int result = Summator()(10, 20); // result will be 30

谓词:布尔判断的精简形式

谓词是返回布尔值的特殊类型的仿函数。它们通常用于表示条件或逻辑测试。与仿函数类似,谓词也是按值传递的,并且可以通过括号运算符调用。

以下是一个谓词,用于检查数字是否大于 5:

struct IsGreaterThan5 {
  bool operator()(int n) {
    return n > 5;
  }
};

使用这个谓词,我们可以过滤大于 5 的数字列表:

std::vector<int> numbers = {1, 4, 6, 8, 10};
std::vector<int> filtered = std::filter(numbers.begin(), numbers.end(), IsGreaterThan5());

NDK 中的仿函数和谓词

在 NDK 中,仿函数和谓词在 native 代码和 Java 代码之间进行交互时特别有用。通过使用 JNI,我们可以将仿函数或谓词作为参数传递给 Java 方法。这允许我们使用 C++ 的强大功能来增强 Java 代码。

例如,我们可以创建一个 C++ 仿函数,以 JNI 方法作为参数调用:

struct JavaMethodCaller {
  JavaVM* jvm;
  jclass clazz;
  jmethodID methodID;

  JavaMethodCaller(JavaVM* jvm, jclass clazz, jmethodID methodID)
      : jvm(jvm), clazz(clazz), methodID(methodID) {}

  void operator()(JNIEnv* env, jobject object, ...) {
    va_list args;
    va_start(args, object);
    env->CallVoidMethodV(object, methodID, args);
    va_end(args);
  }
};

结语

STL 中的仿函数和谓词提供了强大的工具,可以将功能代码封装成轻量级的对象。通过理解它们之间的区别并有效地利用它们,我们可以增强代码的可读性、可重用性和效率。在 NDK 中,仿函数和谓词成为 native 代码和 Java 代码之间交互的桥梁,进一步扩展了移动开发的可能性。