设为首页 加入收藏

TOP

C++新特性 右值引用 移动构造函数(二)
2015-07-20 17:53:39 来源: 作者: 【 】 浏览:4
Tags:特性 引用 移动 构造 函数
rence3 = rvalue(); // ok A &&rvalue_reference4 = const_rvalue(); // error // 规则四:const右值引用可绑定到const右值和非const右值,不能绑定到左值 const A &&const_rvalue_reference1 = lvalue; // error const A &&const_rvalue_reference2 = const_lvalue; // error const A &&const_rvalue_reference3 = rvalue(); // ok const A &&const_rvalue_reference4 = const_rvalue(); // ok // 规则五:函数类型例外 void fun() {} typedef decltype(fun) FUN; // typedef void FUN(); FUN & lvalue_reference_to_fun = fun; // ok const FUN & const_lvalue_reference_to_fun = fun; // ok FUN && rvalue_reference_to_fun = fun; // ok const FUN && const_rvalue_reference_to_fun = fun; // ok 复制代码

【说明】:(1) 一些支持右值引用但版本较低的编译器可能会允许右值引用绑定到左值,例如g++4.4.4就允许,但g++4.6.3就不允许了,clang++3.2也不允许,据说VS2010 beta版允许,正式版就不允许了,本人无VS2010环境,没测试过。

(2)右值引用绑定到字面值常量同样符合上述规则,例如:int &&rr = 123;,这里的字面值123虽然被称为常量,可它的类型为int,而不是const int。对此C++03标准文档4.4.1节及其脚注中有如下说明:

If T is a non-class type, the type of the rvalue is the cv-unqualified version of T.
In C++ class rvalues can have cv-qualified types (because they are objects). This differs from ISO C, in which non-lvalues never have cv-qualified types.

因此123是非const右值,int &&rr = 123;语句符合上述规则三。

此,我们已经了解了不少右值引用的知识点了,下面给出了一个完整地利用右值引用实现move语意的例子:

复制代码
#include 
  
   
#include 
   
     #define PRINT(msg) do { std::cout << msg << std::endl; } while(0) template 
    
      struct remove_reference {typedef _Tp type;}; template 
     
       struct remove_reference<_Tp&> {typedef _Tp type;}; template 
      
        struct remove_reference<_Tp&&> {typedef _Tp type;}; template 
       
         inline typename remove_reference<_Tp>::type&& move(_Tp&& __t) { typedef typename remove_reference<_Tp>::type _Up; return static_cast<_Up&&>(__t); } class A { public: A(const char *pstr) { PRINT("constructor"); m_data = (pstr != 0 ? strcpy(new char[strlen(pstr) + 1], pstr) : 0); } A(const A &a) { PRINT("copy constructor"); m_data = (a.m_data != 0 ? strcpy(new char[strlen(a.m_data) + 1], a.m_data) : 0); } A &operator =(const A &a) { PRINT("copy assigment"); if (this != &a) { delete [] m_data; m_data = (a.m_data != 0 ? strcpy(new char[strlen(a.m_data) + 1], a.m_data) : 0); } return *this; } A(A &&a) : m_data(a.m_data) { PRINT("move constructor"); a.m_data = 0; } A & operator = (A &&a) { PRINT("move assigment"); if (this != &a) { m_data = a.m_data; a.m_data = 0; } return *this; } ~A() { PRINT("destructor"); delete [] m_data; } private: char * m_data; }; void swap(A &a, A &b) { A tmp(move(a)); a = move(b); b = move(tmp); } int main(int argc, char **argv, char **env) { A a("123"), b("456"); swap(a, b); return 0; }
       
      
     
    
   
  
复制代码

输出结果为:

复制代码
constructor
constructor
move constructor
move assigment
move assigment
destructor
destructor
destructor
复制代码


首页 上一页 1 2 下一页 尾页 2/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇POJ 1699 Best Sequence (DFS+预.. 下一篇UVA - 12005 Find Solutions (最..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: