-
创建一个对象或函数的引用,对象必须是 可复制(
CopyConstructible
)、可赋值(CopyAssignable
) 的。 -
它经常被用作在标准容器(如
std::vector
)中存储引用的机制,而标准容器通常不能保存引用。 -
辅助函数
std::ref
与std::cref
常用于生成std::reference_wrapper
对象。 -
std::reference_wrapper
也用于按引用传递参数给std::bind
或std::thread
的构造函数。 -
能隐式转换成
T&
。
-
在
vector
中存储引用类型:#include <iostream> #include <list> #include <vector> #include <random> #include <functional> #include <algorithm> int main() { std::list<int> l(10); std::iota(l.begin(), l.end(), -4); // 从 -4 开始,逐个 +1 std::vector<std::reference_wrapper<int>> v(l.begin(), l.end()); // 不能在 list 上用 shuffle (要求随机访问),但能在 vector 上使用它 std::shuffle(v.begin(), v.end(), std::mt19937{std::random_device{}()}); std::cout << "Contents of the list: "; for (int n : l) { std::cout << n << ' '; } std::cout << '\n'; std::cout << "Contents of the list, as seen through a shuffled vector: "; for (int i : v) { std::cout << i << ' '; } std::cout << '\n'; std::cout << "Doubling the values in the initial list...\n"; for (int& i : l) { i *= 2; } std::cout << "Contents of the list, after doubling: "; for (int i : l) { std::cout << i << ' '; } std::cout << '\n'; std::cout << "Contents of the list, as seen through a shuffled vector: "; for (int i : v) { std::cout << i << ' '; } std::cout << '\n'; }
输出:
Contents of the list: -4 -3 -2 -1 0 1 2 3 4 5 Contents of the list, as seen through a shuffled vector: -3 2 0 3 -1 4 -4 1 5 -2 Doubling the values in the initial list... Contents of the list, after doubling: -8 -6 -4 -2 0 2 4 6 8 10 Contents of the list, as seen through a shuffled vector: -6 4 0 6 -2 8 -8 2 10 -4
-
声明引用类型的数组
int main() { int x = 5, y = 7, z = 8; std::reference_wrapper<int> arr[] {x, y, z}; // int& arr[]{x,y,z}; // error: declaration of ‘arr’ as array of references for (auto a: arr) std::cout << a << " "; std::cout << std::endl; x = 50; std::cout << "-----------\n"; for (auto a: arr) std::cout << a << " "; }
输出:
5 7 8 ----------- 50 7 8
-
与
T&
和T
隐式转换void func(int& a, int b){ cout << "in func: a = " << a << ", b = " << b << endl; a++; b++; } int main() { int a = 10, b = 20; cout << "in main: a = " << a << ", b = " << b << endl; func(ref(a), ref(b)); // 虽然传递的是 b 的引用,但函数形参不是引用类型 // ,所以函数内的 b 是一个拷贝 cout << "in main: a = " << a << ", b = " << b << endl; return 0; }
输出:
in main: a = 10, b = 20 in func: a = 10, b = 20 in main: a = 11, b = 20
-
T&
与reference_wrapper
区别int main() { cout << boolalpha; int x = 5, y = 7; reference_wrapper<int> r = x; // or auto r = ref(x); cout << is_same<int&, decltype(r.get())>::value << "\n"; // true cout << is_same<int&, decltype(r)>::value << "\n"; // false cout << (&x == &r.get()) << "\n"; // true r = y; cout << (&y == &r.get()) << "\n"; // true r.get()=70; cout << y; // 70 return 0; }
-
包裹函数指针
个人感觉,可以替代 函数指针 了,类似
std::function
void func(int a, int b) { cout << "a = " << a <<","; cout << "b = " << b << endl; } void func1(int i) { cout << "i = " << i << endl; } void func2(const reference_wrapper<void(int,int)>& f){ cout << "in func2 invoke f:" << endl; f(10, 20); } int main() { // 包裹函数指针 int x = 5, y = 7; reference_wrapper<void(int,int)> f0 = func; f0(x, y); // a = 5,b = 7 func2(f0); // in func2 invoke f: // a = 10,b = 20 auto f1 = std::ref(func); f1(5,7); // a = 5,b = 7 using Examp = reference_wrapper<void(int)>; Examp f = func1; f(10); // i = 10 using ExampFc = function<void(int)>; ExampFc ff = func1; ff(20); // i = 20 return 0; }
参考: