#include <functional>
函数对象特性
| 特性 | 说明 | 示例 |
|---|
| 可复制 | 可以复制和移动 | auto adder2 = adder1; |
| 无状态 | 不包含成员变量 | 大小通常为1字节 |
| constexpr | C++14+ 支持常量表达式 | constexpr auto sum = std::plus{}(1, 2); |
| 可调用 | 可以像函数一样调用 | adder(1, 2) |
int main() {
system("chcp 65001");
std::plus<int> addFunc;
auto addFuncCopy = addFunc;
std::cout << "addFuncCopy: " << addFuncCopy(2, 3) << std::endl;
std::cout << "sizeof(std::plus<int>): " << sizeof(std::plus<int>) << std::endl;
std::cout << "sizeof(std::plus<double>): " << sizeof(std::plus<double>) << std::endl;
constexpr auto compile_time_sum = std::plus{}(2, 3);
std::cout << "Compile-time sum: " << compile_time_sum << std::endl;
auto result = addFunc(1, 2);
std::cout << "addFunc: " << result << std::endl;
return 0;
}
算数运算
1、std::plus
C++标准库中的函数对象(仿函数),用于执行加法操作
基本用法
int main() {
system("chcp 65001");
std::cout << std::plus<int>{}(2, 3) << endl;
std::cout << std::plus<double>{}(2.1, 3.2) << endl;
std::cout << std::plus<>{}(2.1, 3) << endl;
std::cout << std::plus{}(21.1, 32) << endl;
std::cout << std::plus{}(std::string("Hello "), "world") << endl;
return 0;
}
与std::accumulate结合
int main() {
system("chcp 65001");
std::vector<int> numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int sum = std::accumulate(numbers.begin(), numbers.end(), 0, std::plus{});
std::cout << "result: " << sum << std::endl;
sum = std::accumulate(numbers.begin(), numbers.end(), 0,
[](int a, int b) { return 2 * a + b; });
std::cout << "result: " << sum << std::endl;
return 0;
}
与范围操作结合
int main() {
system("chcp 65001");
int sum = std::ranges::fold_left(std::views::iota(1, 101), 0, std::plus());
std::cout << "result: " << sum << std::endl;
sum = std::ranges::fold_right(std::views::iota(1, 101), 0, std::plus());
std::cout << "result: " << sum << std::endl;
return 0;
}
2、std::minus
C++标准库中的函数对象(仿函数),用于执行减法操作
基本用法
int main() {
system("chcp 65001");
std::cout << std::minus<int>{}(20, 3) << endl;
std::cout << std::minus<double>{}(20.1, 3.2) << endl;
std::cout << std::minus<>{}(20.1, 3) << endl;
std::cout << std::minus{}(21.1, 3) << endl;
return 0;
}
与std::accumulate结合
int main() {
system("chcp 65001");
std::vector<int> numbers = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int sum = std::accumulate(numbers.begin(), numbers.end(), 0, std::minus{});
std::cout << "result: " << sum << std::endl;
sum = std::accumulate(numbers.begin(), numbers.end(), 0,
[](int a, int b) { return 2 * b - a; });
std::cout << "result: " << sum << std::endl;
return 0;
}
与范围操作结合
int main() {
system("chcp 65001");
auto view = std::views::iota(1, 11)
| std::views::transform([](int a) {return a * 10; })
| std::views::reverse;
int sum = std::ranges::fold_left(view, 0, std::minus());
std::cout << "result: " << sum << std::endl;
sum = std::ranges::fold_right(view, 0, std::minus());
std::cout << "result: " << sum << std::endl;
return 0;
}
3、std::multiplies
C++标准库中的函数对象(仿函数),用于执行乘法操作
int main() {
system("chcp 65001");
std::cout << std::multiplies<int>{}(2, 3) << endl;
std::cout << std::multiplies<double>{}(2.1, 3.2) << endl;
std::cout << std::multiplies<>{}(2.1, 3) << endl;
std::cout << std::multiplies{}(2.1, 3) << endl;
std::vector<int> numbers = { 1, 2, 3, 4, 5 };
int sum = std::accumulate(numbers.begin(), numbers.end(), 1, std::multiplies{});
std::cout << "result: " << sum << std::endl;
sum = std::accumulate(numbers.begin(), numbers.end(), 1,
[](int a, int b) { return 2 * b - a; });
std::cout << "result: " << sum << std::endl;
return 0;
}
4、std::divides
C++标准库中的函数对象(仿函数),用于执行除法操作
int main() {
system("chcp 65001");
std::cout << std::divides<int>{}(3, 2) << endl;
std::cout << std::divides<double>{}(2.1, 3.2) << endl;
std::cout << std::divides<>{}(2.1, 3) << endl;
std::cout << std::divides{}(2.1, 3) << endl;
std::vector<int> numbers = { 1, 2, 3, 4, 5 };
int sum = std::accumulate(numbers.begin(), numbers.end(), 1, std::divides{});
std::cout << "result: " << sum << std::endl;
sum = std::accumulate(numbers.begin(), numbers.end(), 1,
[](int a, int b) { return 2 * b / a; });
std::cout << "result: " << sum << std::endl;
return 0;
}
5、std::modulus
C++标准库中的函数对象(仿函数),用于执行取模操作
int main() {
system("chcp 65001");
std::cout << std::modulus<int>{}(3, 2) << endl;
std::cout << "std::fmod= " << std::fmod(3.1, 2.2) << endl;
std::cout << "std::remainder= " << std::remainder(3.1, 2.2) << endl;
std::vector<int> numbers = { 1, 2, 3, 4, 5 };
int sum = std::accumulate(numbers.begin(), numbers.end(), 1, std::modulus{});
std::cout << "result: " << sum << std::endl;
sum = std::accumulate(numbers.begin(), numbers.end(), 1,
[](int a, int b) { return 2 * b % a; });
std::cout << "result: " << sum << std::endl;
return 0;
}
6、std::negate
C++标准库中的函数对象(仿函数),用于执行取负操作
int main() {
system("chcp 65001");
std::cout << std::negate<int>{}(3) << endl;
std::cout << std::negate<int>{}(-5) << endl;
std::cout << std::negate<double>{}(20.1) << endl;
std::cout << std::negate<double>{}(-3.2) << endl;
std::cout << std::negate<>{}(20.1) << endl;
std::cout << std::negate<>{}(3) << endl;
std::cout << std::negate{}(21.1) << endl;
std::cout << std::negate{}(3) << endl;
std::vector<int> nums = { 1, -2, 3, -4, 5 };
std::vector<int> negated(nums.size());
std::transform(nums.begin(), nums.end(), negated.begin(), std::negate<int>());
for (int x : negated) {
std::cout << x << " ";
}
std::cout << endl;
auto view = std::views::iota(1, 11)
| std::views::transform([](int a) {return a % 2 == 0 ? a : std::negate{}(a); })
| std::views::reverse;
for (auto it : view)
{
std::cout << it << ", ";
}
std::cout << endl;
return 0;
}
逻辑运算
| 函数对象 | 操作 | 参数个数 | 返回类型 | 短路求值? |
|---|
std::logical_and | lhs && rhs | 2 | bool(或推导类型) | ❌ 否 |
std::logical_or | lhs || rhs | 2 | bool(或推导类型) | ❌ 否 |
std::logical_not | !x | 1 | bool(或推导类型) | — |
1、std::logical_and
int main() {
system("chcp 65001");
std::vector<bool> a = { true, false, true, false };
std::vector<bool> b = { true, true, false, false };
std::vector<bool> result(4);
std::vector<int> d = { 1, 0, 1 ,2 };
std::vector<int> e = { 0, 0, 2 ,10 };
std::transform(a.begin(), a.end(), b.begin(), result.begin(), std::logical_and<bool>());
std::cout << "std::logical_and: ";
for (auto it : result)
{
std::cout << boolalpha << it << ", ";
}
std::cout << endl;
std::transform(d.begin(), d.end(), e.begin(), result.begin(), std::logical_and<int>());
std::cout << "std::logical_and: ";
for (auto it : result)
{
std::cout << boolalpha << it << ", ";
}
std::cout << endl;
return 0;
}
2、std::logical_or
int main() {
system("chcp 65001");
std::vector<bool> a = { true, false, true, false };
std::vector<bool> b = { true, true, false, false };
std::vector<bool> result(4);
std::vector<int> d = { 1, 0, 1 ,2 };
std::vector<int> e = { 0, 0, 2 ,10 };
std::cout << "std::logical_or: ";
std::transform(a.begin(), a.end(), b.begin(), result.begin(), std::logical_or<bool>());
for (auto it : result)
{
std::cout << boolalpha << it << ", ";
}
std::cout << endl;
std::cout << "std::logical_or: ";
std::transform(d.begin(), d.end(), e.begin(), result.begin(), std::logical_or<int>());
for (auto it : result)
{
std::cout << boolalpha << it << ", ";
}
std::cout << endl;
return 0;
}
3、std::logical_not
int main() {
system("chcp 65001");
std::vector<bool> a = { true, false, true, false };
std::vector<bool> b = { true, true, false, false };
std::vector<bool> result(4);
std::vector<int> d = { 1, 0, 1 ,2 };
std::vector<int> e = { 0, 0, 2 ,10 };
std::cout << "std::logical_not: ";
std::transform(a.begin(), a.end(), result.begin(), std::logical_not<bool>());
for (auto it : result)
{
std::cout << boolalpha << it << ", ";
}
std::cout << endl;
std::cout << "std::logical_not: ";
std::transform(d.begin(), d.end(), result.begin(), std::logical_not<int>());
for (auto it : result)
{
std::cout << boolalpha << it << ", ";
}
std::cout << endl;
return 0;
}
| 特性 | 内置 (&&,||,!) | std::logical_* | |
|---|
| 短路求值 | ✅ 支持 | ❌ 不支持 | |
| 函数调用 | 是运算符 | 是函数对象 | |
| 可作为参数传递 | ❌ 否 | ✅ 是 | |
| 可用于 STL 算法 | ❌ 否 | ✅ 是 | |
| 类型要求 | 任意可转 bool 类型 | 同左 | |
位运算
| 函数 | 操作 | 参数个数 | 支持类型 | 典型用途 |
|---|
std::bit_and | lhs & rhs | 2 | 整数、枚举、可重载 & 的类型 | 掩码提取、权限检查 |
std::bit_or | lhs | rhs | 2 | 同上 | 标志合并、权限设置 |
std::bit_xor | lhs ^ rhs | 2 | 同上 | 翻转位、加密、校验 |
std::bit_not | ~x | 1 | 同上 | 位反转、掩码生成 |
int main() {
system("chcp 65001");
std::vector<unsigned char> a = { 0b1100, 0b1010, 0b0110 };
std::vector<unsigned char> b = { 0b1010, 0b1100, 0b1111 };
std::vector<unsigned char> result(3);
std::vector<int> d = { 1, 0, 1 };
std::vector<int> e = { 0, 0, 1 };
std::transform(a.begin(), a.end(), b.begin(), result.begin(), std::bit_and<char>());
std::cout << "std::bit_and: ";
for (auto it : result)
{
std::cout << std::bitset<4>(it) << ", ";
}
std::cout << endl;
std::transform(d.begin(), d.end(), e.begin(), result.begin(), std::bit_and<int>());
std::cout << "std::bit_and: ";
for (auto it : result)
{
std::cout << std::bitset<4>(it) << ", ";
}
std::cout << endl;
std::cout << "std::bit_or: ";
std::transform(a.begin(), a.end(), b.begin(), result.begin(), std::bit_or<bool>());
for (auto it : result)
{
std::cout << std::bitset<4>(it) << ", ";
}
std::cout << endl;
std::cout << "std::bit_or: ";
std::transform(d.begin(), d.end(), e.begin(), result.begin(), std::bit_or<int>());
for (auto it : result)
{
std::cout << std::bitset<4>(it) << ", ";
}
std::cout << endl;
std::cout << "std::bit_xor: ";
std::transform(a.begin(), a.end(), b.begin(), result.begin(), std::bit_xor<bool>());
for (auto it : result)
{
std::cout << std::bitset<4>(it) << ", ";
}
std::cout << endl;
std::cout << "std::bit_xor: ";
std::transform(d.begin(), d.end(), e.begin(), result.begin(), std::bit_xor<int>());
for (auto it : result)
{
std::cout << std::bitset<4>(it) << ", ";
}
std::cout << endl;
std::cout << "std::bit_not: ";
std::transform(a.begin(), a.end(), result.begin(), std::bit_not<bool>());
for (auto it : result)
{
std::cout << std::bitset<4>(it) << ", ";
}
std::cout << endl;
std::cout << "std::bit_not: ";
std::transform(d.begin(), d.end(), result.begin(), std::bit_not<int>());
for (auto it : result)
{
std::cout << std::bitset<4>(it) << ", ";
}
std::cout << endl;
return 0;
}
比较
1、std::equal_to
| 特性 | std::equal_to | std::ranges::equal_to |
|---|
| 引入版本 | C++98(透明版 C++14) | C++20 |
| 是否透明 | ✅(仅当使用 <> 时) | ✅(始终透明) |
| 支持异构比较 | ✅(std::equal_to<>) | ✅ |
| 编译期约束检查 | ❌ 无 | ✅ 有(equality_comparable_with 概念) |
| 默认实例 | 需手动构造:
std::equal_to<>{}(a,b) | ✅ 全局常量:
std::ranges::equal_to(a,b) |
| 能否用于关联容器 | ✅(如 map<K, V, std::less<>>) | ❌ 不可(拷贝构造被删除) |
| ADL 友好性 | 一般 | 更好(专为 ranges 设计) |
| 头文件 | <functional> | <functional>(C++20) |
int main() {
system("chcp 65001");
int a = 2, b = 3;
std::cout << boolalpha << std::equal_to<int>{}(a, b) << endl;
std::cout << boolalpha << std::equal_to<>{}(a, b) << endl;
std::cout << boolalpha << std::equal_to{}(a, b) << endl;
std::cout << boolalpha << std::ranges::equal_to{}(42, 42) << endl;
std::ranges::equal_to eq;
std::cout << boolalpha << eq(a, b) << endl;
std::cout << boolalpha << eq(2, 2) << endl;
return 0;
}
2、std::not_equal_to
| 特性 | std::not_equal_to | std::ranges::not_equal_to |
|---|
| 引入版本 | C++98(透明版 C++14) | C++20 |
| 是否透明 | ✅(仅当使用 <> 时) | ✅(始终透明) |
| 支持异构比较 | ✅(如 int vs double) | ✅ |
| 编译期约束检查 | ❌ 无 | ✅ 有(equality_comparable_with<T, U>) |
| 默认实例 | 需手动构造:
std::not_equal_to<>{}(a,b) | ✅ 全局常量:
std::ranges::not_equal_to(a,b) |
| 能否用于关联容器 | ✅(如 map<K, V, less<>>) | ❌ 不可(拷贝构造被删除) |
| 头文件 | <functional> | <functional>(C++20) |
是否 constexpr | C++14 起 ✅ | ✅ |
int main() {
system("chcp 65001");
int a = 2, b = 3;
std::cout << boolalpha << std::not_equal_to<int>{}(a, b) << endl;
std::cout << boolalpha << std::not_equal_to<>{}(a, b) << endl;
std::cout << boolalpha << std::not_equal_to{}(a, b) << endl;
std::cout << boolalpha << std::ranges::not_equal_to{}(42, 42) << endl;
std::ranges::not_equal_to neq;
std::cout << boolalpha << neq(a, b) << endl;
std::cout << boolalpha << neq(2, 2) << endl;
return 0;
}
3、std::greater
| 特性 | std::greater | std::ranges::greater |
|---|
| 引入版本 | C++98(透明版 C++14) | C++20 |
| 是否透明 | ✅(仅当使用 <> 时) | ✅(始终透明) |
| 支持异构比较 | ✅(如 int vs double) | ✅ |
| 编译期约束检查 | ❌ 无 | ✅ 有(totally_ordered_with<T, U>) |
| 默认实例 | 需手动构造:
std::greater<>{}(a,b) | ✅ 全局常量:
std::ranges::greater(a,b) |
| 能否用于关联容器 | ✅ 是!常用 (如 map<K, V, greater<>>) | ❌ 不可(拷贝构造被删除) |
| 头文件 | <functional> | <functional>(C++20) |
是否 constexpr | C++14 起 ✅ | ✅ |
int main() {
system("chcp 65001");
int a = 2, b = 3;
std::cout << boolalpha << std::greater<int>{}(a, b) << endl;
std::cout << boolalpha << std::greater<>{}(a, b) << endl;
std::cout << boolalpha << std::greater{}(a, b) << endl;
std::cout << boolalpha << std::greater{}(2, 3.1) << endl;
std::cout << boolalpha << std::ranges::greater{}(42, 42) << endl;
std::ranges::greater gre;
std::cout << boolalpha << gre(a, b) << endl;
std::cout << boolalpha << gre(2, 2) << endl;
std::cout << boolalpha << gre(3, 2.3) << endl;
std::vector<int> vec = { 1, 3, 2, 5, 4 , 8, 29, 6 };
std::sort(vec.begin(), vec.end(), std::greater<>{});
std::ranges::sort(vec, std::ranges::greater{});
std::ranges::sort(vec, gre);
for (auto it : vec)
{
std::cout << it << ", ";
}
return 0;
}
4、std::less
| 特性 | std::less | std::ranges::less |
|---|
| 引入版本 | C++98(透明版 C++14) | C++20 |
| 是否透明 | ✅(仅当使用 <> 时) | ✅(始终透明) |
| 支持异构比较 | ✅(如 int vs double) | ✅ |
| 编译期约束检查 | ❌ 无 | ✅ 有(totally_ordered_with<T, U>) |
| 默认实例 | 需手动构造:
std::less<>{}(a,b) | ✅ 全局常量:
std::ranges::less(a,b) |
| 能否用于关联容器 | ✅ 是!默认比较器 | ❌ 不可(拷贝构造被删除) |
| 头文件 | <functional> | <functional>(C++20) |
是否 constexpr | C++14 起 ✅ | ✅ |
int main() {
system("chcp 65001");
int a = 2, b = 3;
std::cout << boolalpha << std::less<int>{}(a, b) << endl;
std::cout << boolalpha << std::less<>{}(a, b) << endl;
std::cout << boolalpha << std::less{}(a, b) << endl;
std::cout << boolalpha << std::less{}(2, 3.1) << endl;
std::cout << boolalpha << std::ranges::less{}(42, 42) << endl;
std::ranges::less les;
std::cout << boolalpha << les(a, b) << endl;
std::cout << boolalpha << les(2, 2) << endl;
std::cout << boolalpha << les(3, 2.3) << endl;
std::vector<int> vec = { 1, 3, 2, 5, 4 , 8, 29, 6 };
std::sort(vec.begin(), vec.end(), std::less<>{});
std::ranges::sort(vec, std::ranges::less{});
std::ranges::sort(vec, les);
for (auto it : vec)
{
std::cout << it << ", ";
}
return 0;
}
5、std::greater_equal
| 特性 | std::greater_equal | std::ranges::greater_equal |
|---|
| 引入版本 | C++98(透明版 C++14) | C++20 |
| 是否透明 | ✅(仅当使用 <> 时) | ✅(始终透明) |
| 支持异构比较 | ✅(如 int vs double) | ✅ |
| 编译期约束检查 | ❌ 无 | ✅ 有(totally_ordered_with<T, U>) |
| 默认实例 | 需手动构造:
std::greater_equal<>{}(a,b) | ✅ 全局常量:
std::ranges::greater_equal(a,b) |
| 能否用于关联容器 | ⚠️ 技术上可以,但逻辑错误 | ❌ 不可(拷贝构造被删除) |
| 头文件 | <functional> | <functional>(C++20) |
是否 constexpr | C++14 起 ✅ | ✅ |
int main() {
system("chcp 65001");
int a = 2, b = 3;
std::cout << boolalpha << std::greater_equal<int>{}(a, b) << endl;
std::cout << boolalpha << std::greater_equal<>{}(a, b) << endl;
std::cout << boolalpha << std::greater_equal{}(a, b) << endl;
std::cout << boolalpha << std::greater_equal{}(2, 3.1) << endl;
std::cout << boolalpha << std::ranges::greater_equal{}(42, 42) << endl;
std::ranges::greater_equal ge;
std::cout << boolalpha << ge(a, b) << endl;
std::cout << boolalpha << ge(2, 2) << endl;
std::cout << boolalpha << ge(3, 2.3) << endl;
std::vector<int> vec = { 1, 3, 2, 5, 4 , 8, 29, 6 };
std::sort(vec.begin(), vec.end(), std::greater_equal<>{});
std::ranges::sort(vec, std::ranges::greater_equal{});
std::ranges::sort(vec, ge);
for (auto it : vec)
{
std::cout << it << ", ";
}
return 0;
}
6、std::less_equal
| 特性 | std::less_equal | std::ranges::less_equal |
|---|
| 引入版本 | C++98(透明版 C++14) | C++20 |
| 是否透明 | ✅(仅当使用 <> 时) | ✅(始终透明) |
| 支持异构比较 | ✅(如 int vs double) | ✅ |
| 编译期约束检查 | ❌ 无 | ✅ 有(totally_ordered_with<T, U>) |
| 默认实例 | 需手动构造:
std::less_equal<>{}(a,b) | ✅ 全局常量:
std::ranges::less_equal(a,b) |
| 能否用于关联容器 | ⚠️ 技术上可编译,但逻辑错误 | ❌ 不可(拷贝构造被删除) |
| 头文件 | <functional> | <functional>(C++20) |
是否 constexpr | C++14 起 ✅ | ✅ |
int main() {
system("chcp 65001");
int a = 2, b = 3;
std::cout << boolalpha << std::less_equal<int>{}(a, b) << endl;
std::cout << boolalpha << std::less_equal<>{}(a, b) << endl;
std::cout << boolalpha << std::less_equal{}(a, b) << endl;
std::cout << boolalpha << std::less_equal{}(2, 3.1) << endl;
std::cout << boolalpha << std::ranges::less_equal{}(42, 42) << endl;
std::ranges::less_equal le;
std::cout << boolalpha << le(a, b) << endl;
std::cout << boolalpha << le(2, 2) << endl;
std::cout << boolalpha << le(3, 2.3) << endl;
std::vector<int> vec = { 1, 3, 2, 5, 4 , 8, 29, 6 };
std::sort(vec.begin(), vec.end(), std::less_equal<>{});
std::ranges::sort(vec, std::ranges::less_equal{});
std::ranges::sort(vec, le);
for (auto it : vec)
{
std::cout << it << ", ";
}
return 0;
}
7、std::compare_three_way
三路比较函数对象,用于封装和调用 三路比较运算符(<=>,又称 spaceship operator)。它是实现统一、高效、安全的比较逻辑的核心工具,避免手写多个比较运算符
int main() {
system("chcp 65001");
int a = 2, b = 3;
auto result = std::compare_three_way{}(a, b);
std::cout << "a < b = " << boolalpha << std::is_lt(result) << std::endl;
std::cout << "a <= b = " << boolalpha << std::is_lteq(result) << std::endl;
std::cout << "a > b = " << boolalpha << std::is_gt(result) << std::endl;
std::cout << "a >= b = " << boolalpha << std::is_gteq(result) << std::endl;
std::cout << "a = b = " << boolalpha << std::is_eq(result) << std::endl;
std::cout << "a != b = " << boolalpha << std::is_neq(result) << std::endl;
return 0;
}
| 场景 | 是否推荐 |
|---|
对支持 <=> 的类型排序 | ✅ 强烈推荐 |
| 实现自定义类型的比较 | ✅ 首选 operator<=> |
| 泛型代码中统一比较逻辑 | ✅ 最佳实践 |
| 比较可能含 NaN 的浮点数 | ⚠️ 谨慎(避免用于容器) |
| C++17 或更早项目 | ❌ 不可用 |