template <class T> class reference_wrapper;
该模板类仿真一个 T
类型对象的引用。但行为与普通的引用不太一样。
用类型T
实例化的reference_wrapper
类能包装该类型的一个对象,并产生一个reference_wrapper<T>
类型的对象,该对象就像是一个引用,与普通引用最大的不同是:该引用可以考贝或赋值。
2、构造函数 和 赋值运算符
- 没有默认构造函数
- 可以用一个想要引用的对象构造
- 可以用另一个
reference_wrapper
对象构造
int a = 10;
int b = 100;
reference_wrapper<int> r1 = a;
reference_wrapper<int> r2 = r1; 拷贝构造
r1 = 1; 错误,赋值运算符只接收同类型的对象
r1 = b; 正确,利用 b 构造一个临时对象,再用=运算符赋给 r1
r1 = r2; 正确
3、get
成员
通过get
成员获取到reference_wrapper
所引用的对象,从而进行修改其值等操作。访问所引用的对象的话,直接访问reference_wrapper
对象即可。
int a = 10;
reference_wrapper<int> r1 = a;
cout << r1 << endl;
cout << r1.get() << endl;
r1.get() = 100;
cout << r1.get() << endl;
输出:
10
10
100
4、特殊用法
4.1 可以存入容器中
普通的引用不是对象,所以无法存入任何标准库容器。reference_wrapper
包装的引用就可以被存入容器中。
4.2 可以像普通的引用一样作为实参传入函数
一个reference_wrapper<T>
类型的对象,可以作为实参,传入 形参类型为T
的函数中。
就像下面这样:
void func1(int value) { value = 100; } 不过 value 只是个拷贝,不是引用
void func2(int& value) { value = 1000; } 传入的是引用
int a = 10;
reference_wrapper<int> r = a;
func1(r); 传入的是 r 引用的值的 拷贝
cout << a << endl;
func2(r); 传入的是 r 引用的值的 引用
cout << a << endl;
输出:
10
1000
函数func
的参数类型为int
,而传递给func
的参数确是reference_wrapper
类型的对象。
4.3 其他
- 若
reference_wrapper
包裹的引用是可以调用的,则reference_wrapper
对象也是可调用的 std::ref
和std::cref
通常用来产生一个reference_wrapper对象reference_wrapper
常通过引用传递对象给std::bind
函数或者std::thread
构造函数