在头文件functional中定义,函数模板生成函数调用包装器。

template< class F, class... Args >
/*unspecified*/ bind( F&& f, Args&&... args ); (1)  (since C++11)

template< class R, class F, class... Args >
/*unspecified*/ bind( F&& f, Args&&... args ); (2)  (since C++11)

调用这个包装器就是在调用这个包装起绑定的函数,使用的参数就是参数列表中的参数。

#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)
    // _2的意思就是新函数 f1 的第二个参数绑定到原函数 f 的第一个参数位置
    // 第四个参数传递的是引用,第五个参数传递的是值
    auto f1 = std::bind(f, _2, _1, 42, std::cref(n), n);
    n = 10;
    f1(1, 2, 1001); // 1 is bound by _2, 2 is bound by _1, 1001 is unused
    // 结果是 2 1 42 10 7 其中 1001 是无效的

    // nested bind subexpressions share the placeholders
    auto f2 = std::bind(f, _3, std::bind(g, _3), _3, 4, 5);
    f2(10, 11, 12);
    // 嵌套绑定,f 的第四个和第五个参数值绑定为4和5.
    // f 的第一个和第三个参数绑定为 f2 的第三个参数,为12
    // f 的第二个参数绑定为 g 函数的返回值,g 的参数是 f2 的第三个参数
    // 也就是上面说的 share the placeholders


    // common use case: binding a RNG with a distribution
    std::default_random_engine e;
    std::uniform_int_distribution<> d(0, 10);
    std::function<int()> rnd = std::bind(d, e); // a copy of e is stored in rnd
    // 绑定到函数 d 上,参数是 e ;rnd 是一个函数对象,返回值是int
    for(int n=0; n<10; ++n)
        std::cout << rnd() << ' ';
    std::cout << '\n';

    // bind to a member function
    Foo foo;
    auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1); // 绑定到成员函数上
    // 函数是 print_sum ,对象实例是 foo , 第一个参数是95 ,第二个参数是 f3 的第一个参数
    f3(5);

    // bind to member data
    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::unique_ptr<Foo>(new Foo(foo))) << '\n';}