引用有时会失效
#include <functional>
#include <iostream>
void fun(int& n) {
std::cout << "In fun " << "n:" << n << '\n';
++n;
std::cout << "In fun " << "n:" << n << '\n';
}
int main() {
int n = 1;
std::cout << "Before fun " << "n:" << n << '\n';
fun(n);
std::cout << "After fun " << "n:" << n << '\n';
n = 10;
std::function<void()> bound_fun = std::bind(fun, n);
n = 100;
std::cout << "Before bound_fun " << "n:" << n << '\n';
bound_fun();
std::cout << "After bound_fun " << "n:" << n << '\n';
return 0;
}
输出
Before fun n:1
In fun n:1
In fun n:2
After fun n:2
Before bound_fun n:100
In fun n:10
In fun n:11
After bound_fun n:100
fun
函数的参数n
类型为int&
,直接调用fun
时,左值引用跟随变化,然而当左值引用遇到std::bind
时,左值引用却失效了:fun
函数在std::bind
时n
为10;随后n
被赋值100,100并没有被传递给bound_fun
,bound_fun
携带的仍是std::bind
时的10,有点反直觉。
奇怪的知识增加了
std::bind
有一个特殊点就是参数列表的形参是在定义时就决定的(即使传递的是左值引用),如果想要前后联动需配合std::ref
。
std::ref
示例
#include <functional>
#include <iostream>
void fun(int& n1, int& n2, const int& n3) {
std::cout << "In function " << "n1:" << n1 << " n2:" << n2 << " n3:" << n3 << '\n';
++n1; // 增加存储于函数对象的 n1 副本
++n2; // 增加 main() 的 n2
// ++n3; // 编译错误
}
int main() {
int n1 = 1, n2 = 2, n3 = 3;
std::function<void()> bound_fun = std::bind(fun, n1, std::ref(n2), std::cref(n3));
n1 = 10;
n2 = 11;
n3 = 12;
std::cout << "Before function " << "n1:" << n1 << " n2:" << n2 << " n3:" << n3 << '\n';
bound_fun();
std::cout << "After function " << "n1:" << n1 << " n2:" << n2 << " n3:" << n3 << '\n';
}
输出
Before function n1:10 n2:11 n3:12
In function n1:1 n2:11 n3:12
After function n1:10 n2:12 n3:12