我正在學習C++ Boost庫的asio編程。而且我遇到了很多使用函數bind()的函數,它有函數指針作爲參數。函數綁定的目的
我一直無法理解bind()函數的用法。這就是爲什麼我難以理解使用boost庫的asio的程序。
我不想在這裏尋找任何代碼。我只想知道bind()函數或其任何等價函數的用法。 在此先感謝。
我正在學習C++ Boost庫的asio編程。而且我遇到了很多使用函數bind()的函數,它有函數指針作爲參數。函數綁定的目的
我一直無法理解bind()函數的用法。這就是爲什麼我難以理解使用boost庫的asio的程序。
我不想在這裏尋找任何代碼。我只想知道bind()函數或其任何等價函數的用法。 在此先感謝。
函數模板綁定生成對於f轉發呼叫包裝。 調用這個包裝器相當於調用f,其中一些 參數綁定到args。
檢查example below展示綁定
#include <iostream>
#include <functional>
using namespace std;
int my_f(int a, int b)
{
return 2 * a + b;
}
int main()
{
using namespace std::placeholders; // for _1, _2, _3...
// Invert the order of arguments
auto my_f_inv = bind(my_f, _2, _1); // 2 args b and a
// Fix first argument as 10
auto my_f_1_10 = bind(my_f, 10, _1); // 1 arg b
// Fix second argument as 10
auto my_f_2_10 = bind(my_f, _1, 10); // 1 arg a
// Fix both arguments as 10
auto my_f_both_10 = bind(my_f, 10, 10); // no args
cout << my_f(5, 15) << endl; // expect 25
cout << my_f_inv(5, 15) << endl; // expect 35
cout << my_f_1_10(5) << endl; // expect 25
cout << my_f_2_10(5) << endl; // expect 20
cout << my_f_both_10() << endl; // expect 30
return 0;
}
可以使用綁定操作現有的函數的參數順序,或修復一些參數。這可以在stl容器和算法中特別有用,您可以在其中傳遞簽名與您的需求相匹配的現有庫函數。
例如,如果你想在集裝箱改造所有的雙打功率2,你可以簡單地傳遞這樣做std::transform(begin(dbl_vec), end(dbl_vec), begin(dbl_vec), std::bind(std::pow, _1, 2))
您發佈到boost::asio
服務的任務必須是可調用的,其參數爲零,以便服務可以存儲它們並在擁有備用資源(即空閒線程)後調用它們。假設你想要它調用函數void purr(int kitty)
,爲了給這個服務一個格式,它可以與你需要的綁定kitty
參數給purr
函數。這會給你一個對象,這個對象可以用()
沒有任何你可以提供給服務的參數。
當然,使用C++ 11和lambda函數現在最好的方法是做io_service.post([&](){ purr(3); });
並避免使用bind
。
它可以讓你聯想(或「綁定」)你使用您希望庫調用的函數自己的數據,而無需庫知道有關數據的任何信息。
既然你在看Boost.Asio,看看他們的tutorial for binding arguments to a handler。他們有他們想要的處理程序,它需要指向自己的數據,定時器本身和計數器使用功能:
void print(const boost::system::error_code& /*e*/,
boost::asio::deadline_timer* t, int* count)
{
// ...
}
計時器的async_wait
功能使用戶提供的函數被調用時,定時器到期;但只提供了這些論點中的第一個。該處理器是形式的
void handler(
const boost::system::error_code& error // Result of operation.
);
所以我們可以使用bind
其他兩個要傳遞我們的函數(希望三個參數)變換成一個只想要一個說法,通過指定的值:
t.async_wait(boost::bind(print,
boost::asio::placeholders::error, &t, &count));
bind
的結果是一個函數對象(即一個類型的對象,它重載函數調用操作符operator()
),在這種情況下,它只接受一個參數。參數placeholders::error
表示第一個參數仍然是新函數類型的參數;當調用新函數時,另外兩個參數的值爲&t
和&count
。所以,如果我們這個稱自己爲:
auto f = boost::bind(print, boost::asio::placeholders::error, &t, &count)
f(some_error);
這個本來是調用原有的功能與參數相同的效果:
print(some_error, &t, &count);
現在,當計時器到期時,我們的函數被調用,與我們提供的論點,沒有Asio圖書館需要知道他們的任何事情。
它將一個函數轉換爲另一個函數,其中一個或多個(或零個)參數是固定的。例如,f(x,y)→f(5,y)。 – Noel 2014-12-05 11:37:16
對不起,但我沒有讓你很好。 – 2014-12-05 11:39:10
可能有所幫助:http://www.codeproject.com/Articles/13015/A-look-at-the-Boost-Bind-and-Function-libraries – midor 2014-12-05 12:55:57