截至目前,它的声明如下
复制#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::_2和std::placeholders::_1表示参数的顺序,比如, 上面的代码示例中, 3是func的第一个参数,但是,func在声明时,指定了第一个参数的位置,放在了最后。 所以,上面的代码输出结果: a=4, b=2, c=3。
复制#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