C++11中万能的可调用类型声明std::function<...>

简介:

C++11中,callable object 包括传统C函数,C++成员函数,函数对象(实现了()运算符的类的实例),lambda表达式(特殊函数对象)共4种。程序设计,特别是程序库设计时,经常需要涉及到回调,如果针对每种不同的callable object单独进行声明类型,代码将会非常散乱,也不灵活。如下示例:

 

1
2
3
#include <iostream>
#include <functional>
using  namespace  std;<br><br>
复制代码
// 传统C函数
int c_function(int a, int b)
{
    return a + b;
}

// 函数对象
class Functor
{
public:
    int operator()(int a, int b)
    {
        return a + b;
    }
};

int main(int argc, char** argv)
{
    int(*f)(int, int);    // 声明函数类型,赋值只能是函数指针
    f = c_function;
    cout << f(3, 4) << endl;

    Functor ff = Functor(); // 声明函数对象类型,赋值只能是函数对象
    cout << ff(3, 4) << endl;
}
复制代码
1
<br>幸运的是,C++标准库的头文件里定义了std::function<>模板,此模板可以容纳所有类型的callable object.示例代码如下:
复制代码
#include <iostream>
#include <functional>
using namespace std;

// 传统C函数
int c_function(int a, int b)
{
    return a + b;
}

// 函数对象
class Functor
{
public:
    int operator()(int a, int b)
    {
        return a + b;
    }
};

int main(int argc, char** argv)
{
    // 万能可调用对象类型
    std::function<int(int, int)> callableObject;

    // 可以赋值为传统C函数指针
    callableObject = c_function;
    cout << callableObject(3, 4) << endl;

    // 可以赋值为函数对象
    Functor functor;
    callableObject = functor;
    cout << callableObject(3, 4) << endl;

    // 可以赋值为lambda表达式(特殊函数对象)
    callableObject = [](int a, int b){
        return a + b;
    };
    cout << callableObject(3, 4) << endl;
}
复制代码

std::function<>的这种多态能力确实很强,这样可以定义一个回调列表,而列表的元素可接受的可调用物类型并不相同。如下:

1
 
复制代码
#include <iostream>
#include <functional>
#include <list>
using namespace std;

// 传统C函数
int c_function(int a, int b)
{
    return a + b;
}

// 函数对象
class Functor
{
public:
    int operator()(int a, int b)
    {
        return a + b;
    }
};

int main(int argc, char** argv)
{
    Functor functor;
    std::list<std::function<int(int, int)>> callables;

    callables.push_back(c_function);
    callables.push_back(functor);
    callables.push_back([](int x, int y)->int{
        return x + y;
    });

    for (const auto& e : callables)
    {
        cout << e(3, 4) << endl;
    }
}
复制代码

对于使用C回调机制的程序库来说,C++的std::function<>能兼容传统C函数指针,所以库这一端使用std::function<>代替函数指针,并不会影响旧有客户端程序的编码方式。



本文转自莫水千流博客园博客,原文链接:http://www.cnblogs.com/zhoug2020/p/6867528.html,如需转载请自行联系原作者

相关文章
|
1月前
|
C++
C++ 数学函数、头文件及布尔类型详解
C++ 支持数学操作,如`max`和`min`函数找最大值和最小值,以及`&lt;cmath&gt;`库中的`sqrt`、`round`等数学函数。`bool`类型用于布尔逻辑,取值`true`(1)或`false`(0)。布尔表达式结合比较运算符常用于条件判断,例如在`if`语句中检查年龄是否达到投票年龄。在代码示例中,`isCodingFun`和`isFishTasty`变量分别输出1和0。
122 1
|
29天前
|
C++
C++11 std::lock_guard 互斥锁
C++11 std::lock_guard 互斥锁
10 0
|
2月前
|
安全 程序员 编译器
【C/C++ 泛型编程 进阶篇 Type traits 】C++类型特征探究:编译时类型判断的艺术
【C/C++ 泛型编程 进阶篇 Type traits 】C++类型特征探究:编译时类型判断的艺术
176 1
|
8天前
|
Java 编译器 Linux
【C++11(二)】lambda表达式以及function包装器
【C++11(二)】lambda表达式以及function包装器
|
8天前
|
C++
【C++】std::string 转换成非const类型 char* 的三种方法记录
【C++】std::string 转换成非const类型 char* 的三种方法记录
5 0
|
19天前
|
存储 编译器 Linux
【C++初阶(十)】C++模板(进阶) ---非类型模板参数、模板的特化以及模板的分离编译
【C++初阶(十)】C++模板(进阶) ---非类型模板参数、模板的特化以及模板的分离编译
21 0
|
24天前
|
编译器 C语言 C++
【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例
【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例
|
2月前
|
C++ 容器
【C++】标准库类型string
【C++】标准库类型string
164 3
|
2月前
|
安全 程序员 C++
【C++ 基本知识】现代C++内存管理:探究std::make_系列函数的力量
【C++ 基本知识】现代C++内存管理:探究std::make_系列函数的力量
102 0
|
4天前
|
Serverless 应用服务中间件 数据安全/隐私保护
Serverless 应用引擎操作报错合集之在阿里函数计算中,函数执行超时,报错Function time out after如何解决
Serverless 应用引擎(SAE)是阿里云提供的Serverless PaaS平台,支持Spring Cloud、Dubbo、HSF等主流微服务框架,简化应用的部署、运维和弹性伸缩。在使用SAE过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
15 4