左右值区分
不用左右区分
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;
}