zoukankan      html  css  js  c++  java
  • C++11中的std::function

    http://www.jellythink.com/archives/771

    看看这段代码

    先来看看下面这两行代码:

    std::function<void(EventKeyboard::KeyCode, Event*)> onKeyPressed;
    std::function<void(EventKeyboard::KeyCode, Event*)> onKeyReleased;

    这两行代码是从Cocos2d-x中摘出来的,重点是这两行代码的定义啊。std::function这是什么东西?如果你对上述两行代码表示毫无压力,那就不妨再看看本文,就当温故而知新吧。

    std::function介绍

    类模版std::function是一种通用、多态的函数封装。std::function的实例可以对任何可以调用的目标实体进行存储、复制、和调用操作,这些目标实体包括普通函数、Lambda表达式、函数指针、以及其它函数对象等。std::function对象是对C++中现有的可调用实体的一种类型安全的包裹(我们知道像函数指针这类可调用实体,是类型不安全的)。

    通常std::function是一个函数对象类,它包装其它任意的函数对象,被包装的函数对象具有类型为T1, …,TN的N个参数,并且返回一个可转换到R类型的值。std::function使用 模板转换构造函数接收被包装的函数对象;特别是,闭包类型可以隐式地转换为std::function

    最简单的理解就是:

    通过std::function对C++中各种可调用实体(普通函数、Lambda表达式、函数指针、以及其它函数对象等)的封装,形成一个新的可调用的std::function对象;让我们不再纠结那么多的可调用实体。一切变的简单粗暴。

    怎么使用std::function

    使用std::function的感觉就是“万众归一”,下面就通过实际的代码例子,看看究竟怎么使用std::function。会使用了才是王道。

    #include <functional>
    #include <iostream>
    using namespace std;
    
    std::function< int(int)> Functional;
    
    // 普通函数
    int TestFunc(int a)
    {
        return a;
    }
    
    // Lambda表达式
    auto lambda = [](int a)->int{ return a; };
    
    // 仿函数(functor)
    class Functor
    {
    public:
        int operator()(int a)
        {
            return a;
        }
    };
    
    // 1.类成员函数
    // 2.类静态函数
    class TestClass
    {
    public:
        int ClassMember(int a) { return a; }
        static int StaticMember(int a) { return a; }
    };
    
    int main()
    {
        // 普通函数
        Functional = TestFunc;
        int result = Functional(10);
        cout << "普通函数:"<< result << endl;
    
        // Lambda表达式
        Functional = lambda;
        result = Functional(20);
        cout << "Lambda表达式:"<< result << endl;
    
        // 仿函数
        Functor testFunctor;
        Functional = testFunctor;
        result = Functional(30);
        cout << "仿函数:"<< result << endl;
    
        // 类成员函数
        TestClass testObj;
        Functional = std::bind(&TestClass::ClassMember, testObj, std::placeholders::_1);
        result = Functional(40);
        cout << "类成员函数:"<< result << endl;
    
        // 类静态函数
        Functional = TestClass::StaticMember;
        result = Functional(50);
        cout << "类静态函数:"<< result << endl;
    
        return 0;
    }

    对于各个可调用实体转换成std::function类型的对象,上面的代码都有,运行一下代码,阅读一下上面那段简单的代码。总结了简单的用法以后,来看看一些需要注意的事项:

    • 关于可调用实体转换为std::function对象需要遵守以下两条原则:
      • 转换后的std::function对象的参数能转换为可调用实体的参数;
      • 可调用实体的返回值能转换为std::function对象的返回值。
    • std::function对象最大的用处就是在实现函数回调,使用者需要注意,它不能被用来检查相等或者不相等,但是可以与NULL或者nullptr进行比较。

    为什么要用std::function

    好用并实用的东西才会加入标准的。因为好用,实用,我们才在项目中使用它。std::function实现了一套类型消除机制,可以统一处理不同的函数对象类型。以前我们使用函数指针来完成这些;现在我们可以使用更安全的std::function来完成这些任务。

    还有为什么?我也不知道还有为什么?等以后发现了更好的实际应用实例再回来说为什么吧。

    总结

    C++11的加入,貌似让C++变了一个语言似的,也有了Lambda表达式,好多东西都要去学习,好多新的语言特性。哦,慢慢来吧。

    2014年12月5日 于深圳。

  • 相关阅读:
    Python中所有的关键字
    关于selenium的8种元素定位
    对提示框的操作
    selenium+webservice进行百度登录
    MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled...报错解决
    Vue中使用echarts
    npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142解决方法
    插入排序
    冒泡排序优化
    roject 'org.springframework.boot:spring-boot-starter-parent:XXX' not found 解决
  • 原文地址:https://www.cnblogs.com/diegodu/p/6180350.html
Copyright © 2011-2022 走看看