C++11新特性应用--实现延时求值(std::function和std::bind)

说是延时求值,注意还是想搞一搞std::function和std::bind。

之前博客《C++11新特性之std::function》注意是std::function怎样实现回调函数。

如今就算是补充吧,再把std::bind进行讨论讨论。

何为Callable Objects?
就可以调用对象,比方函数指针、仿函数、类成员函数指针等都可称为可调用对象。

对象包装器
Function wrapper
Class that can wrap any kind of callable element (such as functions and function objects) into a copyable object, and whose type depends solely on its call signature (and not on the callable element type itself).

An object of a function class instantiation can wrap any of the following kinds of callable objects: a function, a function pointer, a pointer to member, or any kind of function object (i.e., an object whose class defines operator(), including closures).

A decay copy of the wrapped callable object is stored internally by the object, which becomes the function’s target. The specific type of this target callable object is not needed in order to instantiate the function wrapper class; only its call signature.

以下用一段代码:

#include<iostream>
#include<functional>

//普通函数
void func(void)
{
    std::cout << "1" << std::endl;
}

//类的成员函数
class A
{
public:
    static int A_func(int a)
    {
        std::cout << "2" << "(" << a << ")" << std::endl;
        return a;
    }
};

//仿函数
class B
{
public:
    int operator()(int a)
    {
        std::cout << "2" << "(" << a << ")" << std::endl;
        return a;
    }
};

int main()
{
    std::function<void(void)> fun1 = func;
    fun1();

    std::function<int(int)> fun2 = A::A_func;
    std::cout << fun2(123) << std::endl;

    B b;
    fun2 = b;
    std::cout << fun2(123) << std::endl;

    return 0;
}
//输出:
1
2(123)
123
2(123)
123

接下来std::function用于回调就不浪费篇幅了,接下来注意分析std::bind。

何为std::bind?
字面意思。绑定器。
simple
template

#include <iostream>     // std::cout
#include <functional>   // std::bind

// a function: (also works with function object: std::divides<double> my_divide;)
double my_divide(double x, double y) { return x / y; }

struct MyPair {
    double a, b;
    double multiply() { return a*b; }
};

int main() {
    using namespace std::placeholders;    // adds visibility of _1, _2, _3,...

    // binding functions:
    auto fn_five = std::bind(my_divide, 10, 2);              // returns 10/2
    std::cout << fn_five() << '\n';                          // 5

    auto fn_half = std::bind(my_divide, _1, 2);              // returns x/2
    std::cout << fn_half(10) << '\n';                        // 5

    auto fn_invert = std::bind(my_divide, _2, _1);            // returns y/x
    std::cout << fn_invert(10, 2) << '\n';                    // 0.2

    auto fn_rounding = std::bind<int>(my_divide, _1, _2);   // returns int(x/y)
    std::cout << fn_rounding(10, 3) << '\n';                  // 3

    MyPair ten_two{ 10,2 };

    // binding members:

    // returns x.multiply()
    auto bound_member_fn = std::bind(&MyPair::multiply, _1);               

    std::cout << bound_member_fn(ten_two) << '\n';           // 20

    // returns ten_two.a
    auto bound_member_data = std::bind(&MyPair::a, ten_two); 
    std::cout << bound_member_data() << '\n';                // 10

    return 0;
}

_ 1中的 _ 表示的是占位符,由using namespace std::placeholders; 提供。详细的话找机会再研究。

主要看看上面的代码。bind的几种使用方式。
能够看到。能够绑定所有參数,也能够绑定部分參数。

你可能已经感到bind的威力了吧,那不是重点。与function的结合才是重要的:

//#include <iostream>     // std::cout
//#include <functional>   // std::bind
//
 a function: (also works with function object: std::divides<double> my_divide;)
//double my_divide(double x, double y) { return x / y; }
//
//struct MyPair {
//  double a, b;
//  double multiply() { return a*b; }
//};
//
//int main() {
//  using namespace std::placeholders;    // adds visibility of _1, _2, _3,...
//
//                                        // binding functions:
//  auto fn_five = std::bind(my_divide, 10, 2);               // returns 10/2
//  std::cout << fn_five() << '\n';                          // 5
//
//  auto fn_half = std::bind(my_divide, _1, 2);               // returns x/2
//  std::cout << fn_half(10) << '\n';                        // 5
//
//  auto fn_invert = std::bind(my_divide, _2, _1);            // returns y/x
//  std::cout << fn_invert(10, 2) << '\n';                    // 0.2
//
//  auto fn_rounding = std::bind<int>(my_divide, _1, _2);     // returns int(x/y)
//  std::cout << fn_rounding(10, 3) << '\n';                  // 3
//
//  MyPair ten_two{ 10,2 };
//
//  // binding members:
//  auto bound_member_fn = std::bind(&MyPair::multiply, _1); // returns x.multiply()
//  std::cout << bound_member_fn(ten_two) << '\n';           // 20
//
//  auto bound_member_data = std::bind(&MyPair::a, ten_two); // returns ten_two.a
//  std::cout << bound_member_data() << '\n';                // 10
//
//  return 0;
//}

#include<iostream>
#include<functional>

class A {
public:
    int i_ = 0;
    void output(int x, int y)
    {
        std::cout << x << " " << y << std::endl;
    }
};

int main()
{
    A a;
    std::function<void(int, int)> func1 = std::bind(&A::output, &a, std::placeholders::_1,
        std::placeholders::_2);
    func1(1, 2);

    std::function<int&(void)> func2 = std::bind(&A::i_, &a);
    func2() = 888;

    std::cout << a.i_ << std::endl;
    return 0;
}

//输出:
1 2
888

转载于:https://www.cnblogs.com/yutingliuyl/p/7073561.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值