在 C++ 中,算术函子(Arithmetic Functors) 是标准库 <functional>
中提供的一组函数对象,用于封装基本的算术运算(如加、减、乘、除等)。它们本质上是类模板,重载了 operator()
,因此可以像函数一样被调用。这些函子通常与标准算法(如 std::transform
、std::accumulate
)结合使用,提供高效且语义清晰的运算操作。
1. 标准算术函子列表
以下是 C++ 标准库中定义的算术函子:
函子模板 | 运算描述 | 等效表达式 | 示例 |
---|---|---|---|
std::plus<T> | 加法 | a + b | std::plus<int>()(3, 5) → 8 |
std::minus<T> | 减法 | a - b | std::minus<int>()(5, 3) → 2 |
std::multiplies<T> | 乘法 | a * b | std::multiplies<int>()(2, 3) → 6 |
std::divides<T> | 除法 | a / b | std::divides<int>()(6, 2) → 3 |
std::modulus<T> | 取模(求余) | a % b | std::modulus<int>()(7, 3) → 1 |
std::negate<T> | 取负(一元运算) | -a | std::negate<int>()(4) → -4 |
注:
T
是模板参数,表示运算的数据类型(如int
、double
等)。从 C++14 开始,可以使用std::plus<>
(透明运算符函子)自动推导类型。
2. 使用场景
(1) 直接调用
算术函子可以直接实例化并调用:
#include <functional>std::plus<int> add;
int result = add(3, 5); // 等价于 3 + 5 → 8
(2) 与标准算法结合
示例 1:逐元素加法(std::transform
)
#include <algorithm>
#include <vector>std::vector<int> a = {1, 2, 3};
std::vector<int> b = {4, 5, 6};
std::vector<int> result(3);// 对 a 和 b 的对应元素相加,结果存入 result
std::transform(a.begin(), a.end(), b.begin(), result.begin(), std::plus<int>());
// result = {5, 7, 9}
示例 2:累加(std::accumulate
)
#include <numeric>std::vector<int> nums = {1, 2, 3, 4};
int sum = std::accumulate(nums.begin(), nums.end(), 0, std::plus<int>());
// sum = 1 + 2 + 3 + 4 = 10
示例 3:逐元素乘法
std::transform(a.begin(), a.end(), b.begin(), result.begin(), std::multiplies<int>());
// result = {1*4, 2*5, 3*6} = {4, 10, 18}
3. 透明运算符函子(C++14 起)
C++14 引入了透明运算符函子(如 std::plus<>
),可以自动推导参数类型,避免显式指定模板参数:
// 自动推导为 int
std::plus<> add;
int sum = add(3, 5); // 8// 与 std::transform 结合
std::transform(a.begin(), a.end(), b.begin(), result.begin(), std::plus<>());
4. 性能与优化
编译器内联:算术函子是空类(无成员变量),调用
operator()
通常会被编译器内联优化,性能与直接写a + b
相同。并行化(C++17):
#include <execution> std::transform(std::execution::par, a.begin(), a.end(), b.begin(), result.begin(), std::plus<>());
5. 自定义算术函子
如果标准函子不满足需求,可以自定义:
struct Power {double operator()(double a, int exponent) const {return std::pow(a, exponent); // std::pow是 <cmath>头文件中提供的幂运算函数,用于计算一个数的指定次方。}
};std::vector<double> bases = {2.0, 3.0, 4.0};
std::vector<int> exponents = {2, 3, 4};
std::vector<double> results(3);std::transform(bases.begin(), bases.end(), exponents.begin(), results.begin(), Power());
// results = {4.0, 27.0, 256.0}