C++11左右值引用

左右值区分

不用左右区分
int a = 1;int b = a;
通常的所说左值和右值的判断方法
判断对象能否取地址
所谓的左值一般是指一个指向特定内存具有名称的值(具名对象),它有一个相对稳定内存地址,并且有用一段较长的生命周期。而右值则是不指向稳定内存地址匿名值(不具名对象),它的生命周期很短,通常都是暂时性的。

常量左值引用
int &x1=7;       //编译错误
const int &x =11;//编译成功
右值引用语法
int &&k =11;   //右值引用
右值引用的使用

移动语义
  • 自动生成的移动构造函数
  • 移动的风险
值 类别
  • 泛左值和右值
  • 左值、纯右值和将亡值

 

 将左值转换为右值
  • 基本的转换方法
int i=0;
int &&k1=i;//编译失败
int &&k2= static_cast<int&&>(i);//编译成功
万能引用

基本语法

void foo(int &&i){}  //i为右值引用


template<class T>
void bar(T &&t) {}  //t为万能引用

 引用折叠规则

 完美转发

如果想要在参数传递的过程中保持其原有的属性,则需要在传参时调用forward函数:

void Func(int& x)
{
	cout << "左值引用" << endl;
}
void Func(const int& x)
{
	cout << "const 左值引用" << endl;
}
void Func(int&& x)
{
	cout << "右值引用" << endl;
}
void Func(const int&& x)
{
	cout << "const 右值引用" << endl;
}
template<class T>
void PerfectForward(T&& t)
{
	Func(std::forward<T>(t));
}
int main()
{
	int x = 1;

	PerfectForward(x);//左值
	PerfectForward(10);//右值,右值引用再传递时属性是左值
	PerfectForward(move(x));//右值

	const int y = 20;
	PerfectForward(y);//const左值
	PerfectForward(move(y));//const右值
	return 0;
}

用完美转发给简化list提供右值引用的push_back与insert接口:

namespace hwc
{
	template <class T>
	struct list_node
	{
		list_node<T>* _next;
		list_node<T>* _prev;
		T _data;

		list_node(const T& x)
			:_next(nullptr)
			, _prev(nullptr)
			, _data(x)
		{
		}
        //右值引用
		list_node(T&& x)
			:_next(nullptr)
			, _prev(nullptr)
			, _data(forward<T>(x))//完美转发
		{
		}

	};
	template<class T, class Ref, class Ptr>
	struct __list_iterator
	{
		typedef list_node<T> node;
		typedef __list_iterator<T, Ref, Ptr> Self;
		node* _pnode;
		__list_iterator(node*p)
			:_pnode(p)
		{
		}
        //......
	};


	template<class T>
	class list
	{
		typedef list_node<T> node;
	public:
		typedef __list_iterator<T, T&, T*> iterator;
		typedef __list_iterator<T, const T&, const T*> const_iterator;
        
		iterator begin()
		{
			return iterator(_head->_next);
		}

		iterator end()
		{
			return iterator(_head);
		}
		void empty_initialize()
		{
			_head = new node(T());
			_head->_next = _head;
			_head->_prev = _head;

			_size = 0;

		}

		list()
		{
			empty_initialize();
		}

        //左值引用
		void push_back(const T& x)
		{
			insert(end(), x);
		}
        //右值引用
		void push_back(T&& x)
		{
			insert(end(), forward<T>(x));//完美转发
		}
        //左值引用
		iterator insert(iterator pos,const T& x)
		{
			node* newnode = new node(x);
			node* cur = pos._pnode;
			node* prev = cur->_prev;

			newnode->_prev = prev;
			prev->_next = newnode;
			newnode->_next = cur;
			cur->_prev = newnode;

			++_size;
			return iterator(newnode);
		}
        //右值引用
		iterator insert(iterator pos, T&& x)
		{
			node* newnode = new node(forward<T>(x));//完美转发
			node* cur = pos._pnode;
			node* prev = cur->_prev;

			newnode->_prev = prev;
			prev->_next = newnode;
			newnode->_next = cur;
			cur->_prev = newnode;

			++_size;
			return iterator(newnode);
		}
		private:
			node* _head;
			size_t _size;
	};
}
int main()
{
	hwc::list<hwc::string> lt;
	hwc::string s1("111111");
	lt.push_back(s1);//左值——深拷贝

	lt.push_back(hwc::string("222222"));

	lt.push_back("3333333");
	return 0;
}

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值