// Bind_std_function.cpp : 定義控制台應用程序的入口點。 // #include "stdafx.h" #include <iostream> #include <functional> #include <random> #include <memory> //學習bind的用法 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 + 100; } struct Foo { Foo() = default; Foo(const Foo & a) { data = a.data; std::cout << "復制構造" << std::endl; } void print_sum(int n1, int n2) { std::cout << n1 + n2 << '\n'; } int data = 10; }; ////////////////////////////////////////////////////////////////////////// //std::bind的不同的placeholders個數證明調用函數體時需要傳入的參數量及位置 //std::bind的時候目標的函數的參數的順序與bind的時候的順序的一一對應的 ////////////////////////////////////////////////////////////////////////// int _tmain(int argc, _TCHAR* argv[]) { int n = 7; auto f1 = std::bind(f, std::placeholders::_2, std::placeholders::_1, 43, std::cref(n), n); //第一位置 目標函數(f)的第一個參數 是調用時傳的第二個參數 //第二位置 目標函數(f)的第二個參數 是調用時傳的第一個參數 //第三位置 目標函數(f)的第三個參數 是43 //第四位置 目標函數(f)的第四個參數 是n的按址傳遞 //第五位置 目標函數(f)的第五個參數 是n n = 10; f1(1, 2);//相當於f(2,1,43,10,7); using namespace std::placeholders; auto f2 = std::bind(f, _3, std::bind(g, _3), _3, 4, 5); //第一位置 目標函數f的第一個參數 是調用時傳的第三個參數 //第二位置 目標函數f的第二個參數 是調用時傳的g(第三個參數) //第三位置 目標函數f的第三個參數 是調用時傳的第三個參數 //第四位置 目標函數f的第四個參數 是4 //第五位置 目標函數f的第五個參數 是5 //由此可見,調用時的第一個參數和第二個參數是沒有用的。調用時你把第一個或第二個參數傳多少都是沒有用的 f2(1000, 2000, 55);//f(55,g(55),55,4,5); // common use case: binding a RNG with a distribution std::default_random_engine e; std::uniform_int_distribution<> d(0, 10); std::cout << d(e) << std::endl;//生成一個隨機數 std::function<int()> rnd = std::bind(d, e);//rnd就相當於d(e) for (int n = 0; n < 10; ++n) std::cout << rnd() << ' '; std::cout << '\n'; //綁定類成員函數用對象的指針 Foo foo; auto f3 = std::bind(&Foo::print_sum, &foo, 95, _1); f3(5); // 綁定類成員變量 std::cout << "測試綁定類成員" << std::endl; auto f4 = std::bind(&Foo::data, _1); std::cout << f4(foo) << '\n'; //std::cout << f4(&foo) << '\n';//嘗試傳入類對象指針編譯不通過 std::cout << f4(std::cref(foo)) << '\n';//引用包裝傳遞 //測試發現vs2013不支持Foo的智能指針做為f4的參數 system("pause"); return 0; }