C++ std::bind用法詳解

一、介紹

C++11中提供瞭std::bind。bind()函數的意義就像它的函數名一樣,是用來綁定函數調用的某些參數的。

bind的思想實際上是一種延遲計算的思想,將可調用對象保存起來,然後在需要的時候再調用。而且這種綁定是非常靈活的,不論是普通函數、函數對象、還是成員函數都可以綁定,而且其參數可以支持占位符,比如你可以這樣綁定一個二元函數:

auto f = bind(&func, std::placeholders::_1, std::placeholders::_2);調用的時候通過f(1,2)實現調用。所以,我們可簡單的認為std::bind就是std::bind1ststd::bind2nd的加強版。

std::bind函數有兩種函數原型,定義如下:

template< class F, class... Args >
/*unspecified*/ bind( F&& f, Args&&... args );
 
template< class R, class F, class... Args >
/*unspecified*/ bind( F&& f, Args&&... args );

Parameters

f Callable object (function object, pointer to function, reference to function, pointer to member function, or pointer to data member) that will be bound to some arguments
args list of arguments to bind, with the unbound arguments replaced by the placeholders _1, _2, _3... of namespace std::placeholders

二、實例

這裡要先學習仿函數。請參考仿函數的使用

實例1

#include <iostream>
#include <functional>
using namespace std;
 
int TestFunc(int a, char c, float f)
{
    cout << a << endl;
    cout << c << endl;
    cout << f << endl;
 
    return a;
}
 
int main()
{
    auto bindFunc1 = bind(TestFunc, std::placeholders::_1, 'A', 100.1);
    bindFunc1(10); //等於TestFunc(10,'A', 100.1)
 
    cout << "=================================\n";
 
    auto bindFunc2 = bind(TestFunc, std::placeholders::_2, std::placeholders::_1, 100.1);
    bindFunc2('B', 10); //等於TestFunc(10,'B', 100.1)
 
    cout << "=================================\n";
 
    auto bindFunc3 = bind(TestFunc, std::placeholders::_2, std::placeholders::_3, std::placeholders::_1);
    bindFunc3(100.1, 30, 'C'); //等於TestFunc(30,'C', 100.1)
 
    return 0;
}

 

上面這段代碼主要說的是bind中std::placeholders的使用。 std::placeholders是一個占位符。當使用bind生成一個新的可調用對象時,std::placeholders表示新的可調用對象的第 幾個參數和原函數的第幾個參數進行匹配。

auto bindFunc3 = bind(TestFunc, std::placeholders::_2, std::placeholders::_3, std::placeholders::_1);
 
bindFunc3(100.1, 30, 'C');

可以看到,在bind的時候,第一個位置是TestFunc,除瞭這個,參數的第一個位置為占位符std::placeholders::_2,這就表示,調用bindFunc3的時候,它的第二個參數——即30,和TestFunc的第一個參數匹配,所以std::placeholders::_2為30,以此類推,最後,實際執行的是TestFunc(30,’C’, 100.1)。 

實例2

#include <random>
#include <iostream>
#include <memory>
#include <functional>
 
void f(int n1, int n2, int n3, const int& n4, int n5)
{
	std::cout << n1 << ' ' << n2 << ' ' << n3 << ' ' << n4 << ' ' << n5 << '\n';
}
 
int g(int n1)
{
	return n1;
}
 
struct Foo {
	void print_sum(int n1, int n2)
	{
		std::cout << n1 + n2 << '\n';
	}
	int data = 10;
};
 
int main()
{
	using namespace std::placeholders;  // for _1, _2, _3...
 
	// demonstrates argument reordering and pass-by-reference
	int n = 7;
	// (_1 and _2 are from std::placeholders, and represent future
	// arguments that will be passed to f1)
 
	auto f1 = std::bind(f, _2, 42, _1, std::cref(n), n);
	n = 10;
	f1(1, 2, 1001); // 1 is bound by _1, 2 is bound by _2, 1001 is unused
					// makes a call to f(2, 42, 1, n, 7)
 
	// nested bind subexpressions share the placeholders
	auto f2 = std::bind(f, _3, std::bind(g, _3), _3, 4, 5);
	f2(10, 11, 12); // makes a call to f(12, g(12), 12, 4, 5);
 
	// bind to a pointer to member function
	Foo foo;
	auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1);
	f3(5);
 
	// bind to a pointer to data member
	auto f4 = std::bind(&Foo::data, _1);
	std::cout << f4(foo) << '\n';
 
	std::cout << f4(std::make_shared<Foo>(foo)) << '\n'
		<< f4(std::make_unique<Foo>(foo)) << '\n';
 
        return 0;
}

參考:

https://en.cppreference.com/w/cpp/utility/functional/bind

https://blog.csdn.net/qq_37653144/article/details/79285221

https://blog.csdn.net/u013654125/article/details/100140328#commentBox

到此這篇關於C++ std::bind用法詳解的文章就介紹到這瞭,更多相關C++ std::bind用法內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: