c++11 学习
#include <iostream> // std::cout #include <functional> // std::ref #include <thread> // std::thread #include <future> // std::promise, std::future void print_int1(int& value) { std::cout << "value1: " << value << '\n'; // 打印 value: 10. value = 5; } void print_int2(int value) { std::cout << "value2: " << value << '\n'; // 打印 value: 10. value = 5; } int main () { int value1 = 10; int value2 = 20; std::thread t1(print_int1, std::ref(value1)); t1.join(); std::thread t2(print_int2, value2); t2.join(); std::cout << "value1: " << value1 << '\n'; // 打印 value: 10. std::cout << "value2: " << value2 << '\n'; // 打印 value: 10. return 0; }
g++ future.cpp -std=c++1y -g -pthread
.输出:
value1: 10 value2: 20 value1: 5 value2: 20
可见,当函数 print_int1(int&),且std::ref(value1) 时,是传递的引用。
#include <functional>
#include <iostream>
void f(int& n1, int& n2, const int& n3)
{
std::cout << "In function: " << n1 << ' ' << n2 << ' ' << n3 << '\n';
++n1; // increments the copy of n1 stored in the function object
++n2; // increments the main()'s n2
// ++n3; // compile error
}
int main()
{
int n1 = 1, n2 = 2, n3 = 3;
std::function<void()> bound_f = std::bind(f, n1, std::ref(n2), std::cref(n3));
n1 = 10;
n2 = 11;
n3 = 12;
std::cout << "Before function: " << n1 << ' ' << n2 << ' ' << n3 << '\n';
bound_f();
std::cout << "After function: " << n1 << ' ' << n2 << ' ' << n3 << '\n';
}
输出:
Before function: 10 11 12 In function: 1 11 12 After function: 10 12 12
http://zh.cppreference.com/w/cpp/utility/functional/ref
#include <thread> #include <iostream> using namespace std; void func1(int& a) { a++; } void func2(int a) { a++; } int main() { int a = 42; std::thread t1(func1, std::ref(a)); std::thread t2(func2, a); std::thread t3(func2, std::ref(a)); //std::thread t4(func1, a); 编译错误 t1.join(); t2.join(); t3.join(); std::cout << a << std::endl; return 0; }
输出43,注意,func1 的参数是引用,因此要用std::ref, func2的参数是值拷贝,因此传a,对于 thread3,虽然传的是std::ref, 但由于参数是值拷贝,因此不会对a有影响。
对于 thread4,会产生编译错误,还在思考为什么thread3 不会产生编译错误
理解了bind也就好理解上面的thread3 是可以编译通过的原因,
http://www.cnblogs.com/xusd-null/p/3698969.html
(原文:http://blog.think-async.com/2010/04/bind-illustrated.html)
本文解释了bind
是如何工作的。为了清晰,我对图中的语法作了一些简化(例如,省略函数调用操作符的参数类型),并且简化了 bind
的实现.
1. bind
可以用来将用户提供的需要一个参数的函数转换成不需要参数的函数对象。绑定的值(在这个例子中是123)存储在函数对象内并且会被自动传递给用户指定的函数:
2. 参数绑定也可以用于将类成员函数转换成零参数的函数对象。猿类们都知道,非静态成员函数需要一个隐式的 this
参数。这意味着需要绑定一个合适的类实例指针到这个函数对象:
3. 相应地,隐式的 this
指针也可以显式地传递给需要一个参数的函数对象:
4. 函数对象经常同时使用提前绑定的参数和调用时才提供的参数。这个可以用成员函数来实现:
5. 当然也可以使用非成员函数:
6. 有些时候函数对象被调用时会提供多余的参数,而这些参数是目标函数不需要的。bind
会自动忽略这些多余的参数:
7. 这些多余的参数不需要一定在函数对象签名的最后:
8. 最后, bind
还允许重新组织函数对象的参数顺序: