note
- 更多用法,請參考: cppreference
- 用的少,容易忘。
我的理解
- 類似延遲計算。 比如,回調函數,將回調函數傳入后,回調函數不一定馬上被調用。
- 它是一個模板類,調用后將生成一個新的調用對象A。調用該對象A與調用原函數是等價的。
聲明
截至目前,它的聲明如下

需要包含頭文件
#include <functional>
一個例子
代碼
下面的print函數負責輸出參數的值, 通過使用std::bind, 生成一個新的對象 func, 此時, func(a, b, c);與print(a, b, c);**的調用結果是等價的。
#include <functional>
void print(int a, int b, int c)
{
std::cout << "a = " << a << ", b=" << b << ", c=" << c << "\n\n";
}
int main(int argc, char* argv[], char* env[])
{
auto func = std::bind(print, std::placeholders::_2, 2, std::placeholders::_1);
func(3, 4);
return 0;
}
std::placeholders 說明
std::placeholders::_2和std::placeholders::_1表示參數的順序,比如, 上面的代碼示例中, 3是func的第一個參數,但是,func在聲明時,指定了第一個參數的位置,放在了最后。 所以,上面的代碼輸出結果: a=4, b=2, c=3。

注意
- std::bind的函數參數默認使用的是拷貝, 如果需要使用引用,則需要配合std::ref。
- 下面一個例子,幫助理解。
print2函數負責輸出參數的值,且參數都是引用, print2函數內完成對參數的自增
#include <functional>
void print2(int &a, int &b)
{
std::cout << "函數調用:a=" << a << ", b=" << b << "\n";
++a;
++b;
}
int main(int argc, char* argv[], char* env[])
{
int a = 1;
int b = 2;
auto func2 = std::bind(print2, a, std::ref(b));
std::cout << "調用前,a=" << a << ", b=" << b << "\n";
func2();
std::cout << "調用后,a=" << a << ", b=" << b << "\n";
return 0;
}
調用時,盡管都采用了傳入引用的方式,但略有不同。參數a使用的是傳統的方式,參數b采用的是 std::ref的方式。 觀察輸出結果

可以看到,std::bind的參數是以 拷貝的方式,使用 std::ref 的方式可以實現參數在std::bind的引用。
官方的例子
#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);
// common use case: binding a RNG with a distribution
std::default_random_engine e;
std::uniform_int_distribution<> d(0, 10);
auto rnd = std::bind(d, e); // a copy of e is stored in rnd
for(int n=0; n<10; ++n)
std::cout << rnd() << ' ';
std::cout << '\n';
// 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';
// smart pointers can be used to call members of the referenced objects, too
std::cout << f4(std::make_shared<Foo>(foo)) << '\n'
<< f4(std::make_unique<Foo>(foo)) << '\n';
}
官方例子輸出
2 42 1 10 7
12 12 12 4 5
1 5 0 2 0 8 2 2 10 8
100
10
10
10
