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,如需转载请自行联系原作者

相关文章
|
24天前
|
算法 编译器 数据库
【C++ 泛型编程 高级篇】使用SFINAE和if constexpr灵活处理类型进行条件编译
【C++ 泛型编程 高级篇】使用SFINAE和if constexpr灵活处理类型进行条件编译
243 0
|
24天前
|
设计模式 程序员 C++
【C++ 泛型编程 高级篇】C++模板元编程:使用模板特化 灵活提取嵌套类型与多容器兼容性
【C++ 泛型编程 高级篇】C++模板元编程:使用模板特化 灵活提取嵌套类型与多容器兼容性
241 2
|
24天前
|
存储 安全 编译器
【C++ 17 新功能 std::visit 】深入解析 C++17 中的 std::visit:从原理到实践
【C++ 17 新功能 std::visit 】深入解析 C++17 中的 std::visit:从原理到实践
69 0
|
11天前
|
编译器 C语言 C++
【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例
【C++的奇迹之旅(二)】C++关键字&&命名空间使用的三种方式&&C++输入&输出&&命名空间std的使用惯例
|
22天前
|
安全 程序员 C++
【C++ 基本知识】现代C++内存管理:探究std::make_系列函数的力量
【C++ 基本知识】现代C++内存管理:探究std::make_系列函数的力量
96 0
|
24天前
|
存储 安全 编译器
【C++ 函数设计的艺术】深挖 C++ 函数参数的选择 智能指针与 std::optional:最佳实践与陷阱
【C++ 函数设计的艺术】深挖 C++ 函数参数的选择 智能指针与 std::optional:最佳实践与陷阱
106 0
|
24天前
|
算法 测试技术 编译器
【C++ 基本类型 bool 】深入探索C++中的布尔类型Boolean(二 )
【C++ 基本类型 bool 】深入探索C++中的布尔类型Boolean
25 0
|
24天前
|
程序员 编译器 C语言
【C++ 基本类型 bool 】深入探索C++中的布尔类型Boolean(一)
【C++ 基本类型 bool 】深入探索C++中的布尔类型Boolean
37 0
|
24天前
|
存储 安全 编译器
【C++ 17 泛型容器对比】C++ 深度解析:std::any 与 std::variant 的细微差别
【C++ 17 泛型容器对比】C++ 深度解析:std::any 与 std::variant 的细微差别
46 1
|
24天前
|
算法 编译器 C++
【C++ 泛型编程 中级篇】C++ 编译时技术:探索 if constexpr 和 std::enable_if
【C++ 泛型编程 中级篇】C++ 编译时技术:探索 if constexpr 和 std::enable_if
36 0

热门文章

最新文章