在 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}