c++之函數對象、bind函數


函數對象實質上是一個實現了operator()--括號操作符--的類。

class Add
{
public:
    int operator()(int a, int b)
    {
        return a + b;
    }
};

int main()
{
    Add add; // 定義函數對象
    cout << add(3, 2); // 5

    system("pause");
    return 0;
}

函數指針版本就是:

int AddFunc(int a, int b)
{
    return a + b;
}
typedef int(*Add) (int a, int b);

int main()
{
    Add add = &AddFunc;
    cout << add(3, 2); // 5  //(*add)(3,2)

    system("pause");
    return 0;
}

既然函數對象與函數指針在使用方式上沒什么區別,那為什么要用函數對象呢?很簡單,函數對象可以攜帶附加數據,而指針就不行了。
下面就舉個使用附加數據的例子:

class Less
{
public:
    Less(int num) :n(num) {}
    bool operator()(int value)
    {
        return value < n;
    }
private:
    int n;
};

int main()
{
    Less isLess(10);
    cout << isLess(9) << " " << isLess(12); // 輸出 1 0

    system("pause");
    return 0;
}

 bind是這樣一種機制,它可以預先把指定函數的某些參數綁定到已有的變量,產生一個新的函數,這種機制在回調函數的使用過程中也頗為有用。

int Func(int x, int y)
{
    return x + y;
}

int main()
{
    //bf1把擁有兩個參數的普通函數的第一個參數綁定為10,生成了一個新的一個參數的函數
    auto bf1 = std::bind(Func, 10, std::placeholders::_1);
    cout<<bf1(20); ///< same as Func(10, 20)  

    system("pause");
    return 0;
}

 

class A
{
public:
    int Func(int x, int y)
    {
        return x + y;
    }
};


int main()
{
    A a;
    //bf2把一個類成員函數綁定了類對象,生成了一個像普通函數一樣的新的可調用實體
    auto bf2 = std::bind(&A::Func, a, std::placeholders::_1, std::placeholders::_2);
    cout << bf2(10, 20); ///< same as a.Func(10, 20)  

    system("pause");
    return 0;
}

使用bind需要注意的一些事項:

  • (1)bind預先綁定的參數需要傳具體的變量或值進去,對於預先綁定的參數,是pass-by-value的
  • (2)對於不事先綁定的參數,需要傳std::placeholders進去,從_1開始,依次遞增。placeholder是pass-by-reference的
  • (3)bind的返回值是可調用實體,可以直接賦給std::function對象
  • (4)對於綁定的指針、引用類型的參數,使用者需要保證在可調用實體調用之前,這些參數是可用的
  • (5)類的this可以通過對象或者指針來綁定

 

 

參考:http://blog.csdn.net/crayondeng/article/details/9996625

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM