zoukankan      html  css  js  c++  java
  • C++11 std::function、std::bind和lambda表达式

      参考博客: C++可调用对象详解-https://www.cnblogs.com/Philip-Tell-Truth/p/5814213.html

      一、关于std::function与std::bind

      翻看了几篇博客,还不如看书逻辑性好。以下内容摘自祁宇《深入应用C++11: 代码优化与工程级应用》一书。

      有以下4种情况可被称为可调用对象。

      1、是一个函数指针。(这里的函数要求是如C函数一样的编译期内存确定的函数指针)

      2、是一个具有operator()成员函数的类对象。(让类重载调用操作符operator(),关键在于是以类对象调用形式调用)

      3、是一个可被转换为函数指针的类对象。(这一点与2是一样的,函数可以使用函数名+operator的形式调用,也可以使用函数指针如  void(*p)(int); p = test;

        (*p) (n); 注意看下面例子中的这一种情况)

      4、是一个类成员(函数)指针。

      例子:

      void func( void) { // ... }

      struct Foo {

        void operator()( void) { // ... }

       };

      struct Bar {

        using fr_ t = void(*)( void);       //void (*)(void)相当定义了一种函数指针类型!!!

        static void func( void) { // ... }   //一定要是static

        operator fr_ t( void) { return func; }

      };

      struct A{

        int a_;

        void mem_ func( void) { // ... }

      };

      使用:

       int main( void) {

        void(* func_ ptr)( void) = &func; // 1. 函数 指针

        func_ ptr();

        Foo foo; // 2. 仿 函数

        foo();

        Bar bar; // 3. 可被 转换 为 函数 指针 的 类 对象

        bar();

        void (A::* mem_ func_ ptr)( void)= &A:: mem_ func;  // 4. 类 成员 函数 指针 

        int A::* mem_ obj_ ptr = &A:: a_;                               // 或者是 类 成员 指针  

                  A aa;

        (aa.* mem_ func_ ptr)();

             aa.* mem_ obj_ ptr = 123;

                  return 0;

    }

      std::function是可调用对象的包装器(也就是说std::function对上面几种情况做了封装),可以容纳除了类成员(函数)指针外(不包括上面列出来的4!)的所有可调用对象。通过制定它的模板参数,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存于延迟执行他们。 

      如定义  std::function<void (void)> fc = func;  fc(); //等同于调用func

      std::function包括了C++中的可调用对象,让上述列出来的签3中情况就有了一个方便操作的对象属性。

        std::bind可以让上面的第4中情况也变成一个方便使用的std::function对象,C++中函数指针的使用一定要上调用者对象。

      如下代码:

      #include < iostream>

      #include < functional>

      class A {

        public:

        int i_ = 0;

        void output( int x, int y) { std:: cout << x << " " << y << std:: endl;}

       };

      int main( void)

      {

        A a;

        std:: function< void( int, int)> fr = std:: bind(& A:: output, &a, std:: placeholders::_ 1 , std:: placeholders::_ 2);

        fr( 1, 2);

      }

      针对类成员函数指针,std::bind就填入了调用者a的地址值,使它变成了一个方便易用的std::function对象。

      二、lambda表达式

      语法:[ capture ] ( params ) opt -> ret { body; };

      其中最有意思的应该是capture这个属性了吧。有空来补充吧,吃饭去!

  • 相关阅读:
    前端性能优化
    技术从业者的未来(二)
    微服务架构
    SpringCloud 微服务最佳开发实践
    架构师之路
    SpringBoot开发秘籍
    架构设计方法论
    消息架构的设计难题以及应对之道
    SpringCloud 中如何防止绕过网关请求后端服务?
    微服务架构授权是在网关做还是在微服务做?
  • 原文地址:https://www.cnblogs.com/kanite/p/8324236.html
Copyright © 2011-2022 走看看