C++学习笔记(三十五)——STL之仿函数

一、仿函数(Functor)

(1)仿函数与其适用场景

仿函数(Functor,Function Object)是重载 operator() 的类或结构体对象,它的行为类似于函数,可以像普通函数一样被调用。

特点:

  • 可以携带状态:仿函数可以存储数据,而普通函数无法做到这一点。
  • 性能优化:在 STL 算法(如 sortfor_each)中,仿函数的执行比函数指针更快。
  • 增强可读性:自定义运算逻辑,提高代码的灵活性。

适用场景:

  • 排序 (sortstable_sort)
  • 变换 (transformfor_each)
  • 查找 (find_if)
  • 过滤 (remove_if)

头文件:

#include <functional>

(2)普通函数 vs 仿函数

功能普通函数仿函数(Functor)
是否可以存储状态
性能较慢更快(内联优化)
适用于 STL 算法更推荐
可读性适中更灵活

二、STL 算术仿函数

仿函数作用
plus<T>
minus<T>
multiplies<T>
divides<T>
modulus<T>取模
negate<T>数值取反

示例1——使用 plus<int> 进行加法:

#include <iostream>
using namespace std;
#include <functional>  // 引入 STL 仿函数

int main() {
    plus<int> add;  // 定义加法仿函数
    cout << "10 + 20 = " << add(10, 20) << endl;

    system("pause");
    return 0;
}

示例2——transform 结合仿函数:

#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <functional>

int main() {
    vector<int> v1 = {1, 2, 3, 4};
    vector<int> v2 = {10, 20, 30, 40};
    vector<int> result(4);

    // 使用 plus<int> 计算 v1 + v2
    transform(v1.begin(), v1.end(), v2.begin(), result.begin(), plus<int>());

    for (int num : result)
    {
        cout << num << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}

注意:

  • transform函数的作用是用于对容器或指定迭代器范围的每个元素进行指定的“转换操作”,并将“转换结果”存储到另一个容器中 ;
  • transform函数接受一个或两个输入范围 , 以及一个输出范围 ,并根据提供的一元函数对象或二元函数对象对“输入范围内的元素”进行转换 ;
  • std::plus<int>()transform 自动执行加法运算。

三、STL 关系仿函数

仿函数作用
equal_to<T>等于
not_equal_to<T>不等于
greater<T>大于
less<T>小于
greater_equal<T>大于或等于
less_equal<T>小于或等于

示例——使用 greater<int> 进行降序排序:

#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <functional>

int main() {
    vector<int> nums = { 5, 2, 8, 3, 1 };

    // 使用 greater<int> 进行降序排序
    sort(nums.begin(), nums.end(), greater<int>());

    for (int num : nums)
    {
        cout << num << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}

注意:

  • greater<int>() 代替了 operator()(int a, int b) { return a > b; }

四、STL 逻辑仿函数

仿函数作用
logical_and<T>逻辑与
logical_or<T>逻辑或
logical_not<T>逻辑非

示例——logical_not<bool> 取反:

#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>
#include <functional>

int main() {
    vector<bool> v = { true, false, true, false };

    vector<bool> result(4);

    // 取反
    transform(v.begin(), v.end(), result.begin(), logical_not<bool>());

    for (bool b : result)
    {
        cout << boolalpha << b << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}

注意:

  • std::logical_not<bool>()transform 自动执行对容器v中的元素取反,并保存到result容器中

五、STL 位运算仿函数

仿函数作用
bit_and<T>按位与
bit_or<T>按位或
bit_xor<T>按位异或
bit_not<T>按位取反

示例——计算所有元素的按位与:

#include <iostream>
using namespace std;
#include <vector>
#include <functional>
#include <numeric>  // std::accumulate
#include <bitset>

int main() {
    vector<int> nums = { 0b1111, 0b1010, 0b1100 }; // 二进制: {15, 10, 12}

    // 使用 std::bit_and<> 计算所有元素的按位与
    int result = accumulate(nums.begin(), nums.end(), ~0, bit_and<int>());

    cout << "按位与结果: " << result << " (二进制: " << bitset<4>(result) << ")" << endl;

    system("pause");
    return 0;
}

注意:

  • accumulate函数用来计算特定范围内(包括连续的部分和初始值)所有元素的和,除此之外,还可以用指定的二进制操作计算特定范围内的元素结果
  • accumulate(nums.begin(), nums.end(), ~0, bit_and<int>());~0元素累计运算的初始值(即二进制数全1为初始值)。

六、自定义仿函数

示例——仿函数实现自定义排序:

#include <iostream>
using namespace std;
#include <vector>
#include <algorithm>

// 自定义仿函数(奇数优先排序)
class CustomSort
{
public:
    bool operator()(int a, int b)
    {
        return (a % 2) > (b % 2); // 让奇数排前面
    }
};

int main() {
    vector<int> nums = { 3, 6, 1, 8, 5, 2 };

    // 使用自定义仿函数
    sort(nums.begin(), nums.end(), CustomSort());

    for (int num : nums)
    {
        cout << num << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}

注意:

  • CustomSort()sort() 按照“奇数优先”排序!
### 关于ArcGIS License Server无法启动的解决方案 当遇到ArcGIS License Server无法启动的情况时,可以从以下几个方面排查并解决问题: #### 1. **检查网络配置** 确保License Server所在的计算机能够被其他客户端正常访问。如果是在局域网环境中部署了ArcGIS Server Local,则需要确认该环境下的网络设置是否允许远程连接AO组件[^1]。 #### 2. **验证服务状态** 检查ArcGIS Server Object Manager (SOM) 的运行情况。通常情况下,在Host SOM机器上需将此服务更改为由本地系统账户登录,并重启相关服务来恢复其正常工作流程[^2]。 #### 3. **审查日志文件** 查看ArcGIS License Manager的日志记录,寻找任何可能指示错误原因的信息。这些日志可以帮助识别具体是什么阻止了许可证服务器的成功初始化。 #### 4. **权限问题** 确认用于启动ArcGIS License Server的服务账号具有足够的权限执行所需操作。这包括但不限于读取/写入特定目录的权利以及与其他必要进程通信的能力。 #### 5. **软件版本兼容性** 保证所使用的ArcGIS产品及其依赖项之间存在良好的版本匹配度。不一致可能会导致意外行为或完全失败激活license server的功能。 #### 示例代码片段:修改服务登录身份 以下是更改Windows服务登录凭据的一个简单PowerShell脚本例子: ```powershell $serviceName = "ArcGISServerObjectManager" $newUsername = ".\LocalSystemUser" # 替换为实际用户名 $newPassword = ConvertTo-SecureString "" -AsPlainText -Force Set-Service -Name $serviceName -StartupType Automatic New-ServiceCredential -ServiceName $serviceName -Account $newUsername -Password $newPassword Restart-Service -Name $serviceName ``` 上述脚本仅作为示范用途,请依据实际情况调整参数值后再实施。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奕天者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值