int main()
{
int i = 0;
/*
std::ref 把对象包装了一下,通过get方法获取对象的引用,通过修改引用最终修改了对象。
一些std方法不支持直接传引用,比如std::thread std::async,编译会报错;
一些方法又把引用 decay 成值了,没有完成初衷,比如 std::bind
*/
{
auto wp = std::ref(i);
int& value = wp.get();
value = 30;
std::cout << i << std::endl;//输出30
}
{
std::thread th([&](int& i) {i = 10; }, std::ref(i));
th.join();
std::cout << i << std::endl;//输出10
}
{
auto fur = std::async([&](int& i) {i = 20; }, std::ref(i));
fur.get();
std::cout << i << std::endl;//输出20
}
{
std::function<void()> bound = std::bind([&](int& i) {i = 40; }, std::ref(i));
bound();
std::cout << i << std::endl;//输出40
//把引用 decay 成值了
bound = std::bind([&](int& i) {i = 10; }, i);
std::cout << i << std::endl;//输出40
}
return 0;
}
还有 std::cref 区别在于在方法中不能修改值。一些std方法不支持直接传引用,一个原因就是数据要被异步处理,数据正在被处理却在外边被析构的话是不行的。传入std::ref 代表使用者清楚的知道在处理完成之前数据不会被析构,管理数据生命周期的责任在使用者。