C++ 什么时候使用std::ref

一,ref的含义

ref(obj)返回值可以简单理解为一个ref类对象,在此对象中有一个变量指针指向obj的地址,也就是说ref类中的数据包含了obj的引用。当然,实际实现和这个描述有一定区别,但你可以简单这样理解。

二,为什么要引入ref

看一下这段代码:

#include <iostream>
#include <thread>
#include <functional>

using namespace std;

void thread_fun(int& n)
{
	n++;
}

int main()

{
	int num = 0;

	//需要在thread中修改num的值,需要把num的引用作为参数传递给thread
	thread t1(thread_fun, num);
	t1.join();

	cout << "num = " << num << endl;
}

在这段代码中,我们要实现一个线程thead_fun,并且在线程中改变num的值。但代码是编译失败的。我们看一下thread的定义,找到如下构造函数:

    _NODISCARD_CTOR_THREAD explicit thread(_Fn&& _Fx, _Args&&... _Ax) {
        _Start(_STD forward<_Fn>(_Fx), _STD forward<_Args>(_Ax)...);
    }

看一下_Args&&, 这个是右值引用,所以thread t1(thread_fun, num);语句中的num会转成右值引用。但函数中void thread_fun(int& n)的参数为左值引用,正是这个原因导致编译失败。

如果想编译通过,需要把代码中的thread t1(thread_fun, num); 改为thread t1(thread_fun, ref(num));

三,什么时候需要使用ref

看代码:

#include <iostream>
#include <thread>
#include <tuple>
#include <functional>

using namespace std;

void thread_fun(int& n)
{
	n++;
}

void func(int& n)
{
	n++;
}

int main()

{
	int num = 0;

	//需要在thread中修改num的值,需要把num的引用作为参数传递给thread
	thread t1(thread_fun, ref(num));
	t1.join();

	cout << "num = " << num << endl;

	//绑定函数中,需要传递参数引用给函数。
	function<void()> f = bind(func, ref(num));
	f();

	cout << "num = " << num << endl;

	//tuple中需要使用引用
	int a = 1;
	int b = 2;
	int c = 3;

	tuple<int&,int,int> t = make_tuple(ref(a), b, c);
	cout << "a = " << a << endl;
	cout << "b = " << b << endl;
	cout << "c = " << c << endl;

	get<0>(t) = 4;
	cout << "a = " << a << endl;

}

bind函数原型如下:

_NODISCARD _CONSTEXPR20 _Binder<_Unforced, _Fx, _Types...> bind(_Fx&& _Func, _Types&&... _Args) {
    return _Binder<_Unforced, _Fx, _Types...>(_STD forward<_Fx>(_Func), _STD forward<_Types>(_Args)...);
}

看_Types&&... _Args这个也是右值引用。

make_tuple原型如下:

_NODISCARD constexpr tuple<_Unrefwrap_t<_Types>...> make_tuple(_Types&&... _Args) { // make tuple from elements
    using _Ttype = tuple<_Unrefwrap_t<_Types>...>;
    return _Ttype(_STD forward<_Types>(_Args)...);
}

参数_Types&&... _Args也是右值引用。

总结:如果参数是右值引用的情况下要传递引用,则需使用ref

  • 17
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值