程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++11新特性應用--實現延時求值(std::function和std::bind)

C++11新特性應用--實現延時求值(std::function和std::bind)

編輯:C++入門知識

C++11新特性應用--實現延時求值(std::function和std::bind)


說是延時求值,注意還是想搞一搞std::function和std::bind。

現在就算是補充吧,再把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
#include

//普通函數
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 fun1 = func;
    fun1();

    std::function 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      // std::cout
#include    // std::bind

// a function: (also works with function object: std::divides 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(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      // std::cout
//#include    // std::bind
//
//// a function: (also works with function object: std::divides 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(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
#include

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

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

    std::function func2 = std::bind(&A::i_, &a);
    func2() = 888;

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

//輸出:
1 2
888

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved