c++ std::reference_wrapper

reference_wrapper

reference_wrapper是一个模板类

template <class T> class reference_wrapper;

用类型T实例化的reference_wrapper类能包装该类型的一个对象,并产生一个reference_wrapper< T >类型的对象,该对象就像是一个引用,与普通引用最大的不同是:该引用可以拷贝或赋值。

特点:没有默认构造函数,可以用一个想要引用的对象构造,或者用另一个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;			正确

get函数

ref()返回的是一个reference_wrapper对象,并不是该对象的引用,所以如果要对返回对象调用成员函数就会报错。使用reference wrapper对象的get()方法,返回真正的引用(实际上reference wrapper是用指针表现出引用的所有特性,所以返回的应该是指针指向的对象)。

通过get成员获取到reference_wrapper所引用的对象,从而进行修改其值等操作。访问所引用的对象的话,直接访问reference_wrapper对象即可

int a = 10;
reference_wrapper<int> r1 = a;
cout << r1 << endl;	// 10
cout << r1.get() << endl;	// 10
r1.get() = 100;
cout << r1.get() << endl;	// 100

特殊用法

可以存入容器中
普通的引用不是对象,所以无法存入任何标准库容器。reference_wrapper包装的引用就可以被存入容器中。

可以像普通的引用一样作为实参传入函数
一个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;	 10
func2(r);		传入的是 r 引用的值的 引用
cout << a << endl;	1000

函数func的参数类型为int,而传递给func的参数确是reference_wrapper类型的对象。

  • 若reference_wrapper包裹的引用是可以调用的,则reference_wrapper对象也是可调用的
  • reference_wrapper 常通过引用传递对象给std::bind函数或者std::thread构造函数
  • std::ref 和std::cref 通常用来产生一个reference_wrapper对象,ref()就是用reference_wrapper来包裹对象的一个简化写法。
auto r=ref(o);
//等价于
referencce_wrapper<dectype(o)> r(o);

示例

#include <functional>
using namespace std;

void func(int a, int b)
{
    cout << "a = " << a <<",";
    cout << "b = " << b << endl;
}

void func1(int i)
{
    cout << "i = " << i << endl;
}

int main()
{
    // 包裹函数指针
    std::reference_wrapper<void(int,int)> f0 = func;
    f0(5,7); 		// a = 5,b = 7

    auto f1 = std::ref(func);
    f1(5,7);		// a = 5,b = 7

    // 和bind结合使用
    int i = 10;

    auto f2 = std::bind(func1, i);
    auto f3 = std::bind(func1, std::ref(i));

    i = 30;

    f2();	// i = 10
    f3();	// i = 30

    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
In file included from /home/yhdr/2-test-2023-06_v3/sent.h:24:0, from /home/yhdr/2-test-2023-06_v3/sent.cpp:1: /usr/include/c++/7/thread: In instantiation of ‘struct std::thread::_Invoker<std::tuple<void (*)(double*, double&, double&, double&, double&, double&), double**, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double> > >’: /usr/include/c++/7/thread:127:22: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(double*, double&, double&, double&, double&, double&); _Args = {double**, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>}]’ /home/yhdr/2-test-2023-06_v3/sent.cpp:18:153: required from here /usr/include/c++/7/thread:240:2: error: no matching function for call to ‘std::thread::_Invoker<std::tuple<void (*)(double*, double&, double&, double&, double&, double&), double**, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double> > >::_M_invoke(std::thread::_Invoker<std::tuple<void (*)(double*, double&, double&, double&, double&, double&), double**, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double> > >::_Indices)’ operator()() ^~~~~~~~ /usr/include/c++/7/thread:231:4: note: candidate: template<long unsigned int ..._Ind> decltype (std::__invoke((_S_declval<_Ind>)()...)) std::thread::_Invoker<_Tuple>::_M_invoke(std::_Index_tuple<_Ind ...>) [with long unsigned int ..._Ind = {_Ind ...}; _Tuple = std::tuple<void (*)(double*, double&, double&, double&, double&, double&), double**, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double>, std::reference_wrapper<double> >] _M_invoke(_Index_tuple<_Ind...>)
06-07

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值