程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++0x,std::move和std::forward解析

C++0x,std::move和std::forward解析

編輯:C++入門知識

C++0x,std::move和std::forward解析


1.std::move   1.1std::move是如何定義的     template<typename _Tp>     constexpr typename std::remove_reference<_Tp>::type&&     move(_Tp&& __t) noexcept     { return static_cast<typename std::remove_reference<_Tp>::type&&>(__t); } 1.2 std::move是如何工作的   1.2.1傳入一個右值      a.如果傳入是一個右值string,比如“hello”,推斷出_Tp類型為string      b.std::remove_reference<_Tp>::type的類型依舊為string      c.move函數的返回類型為string&&      d.move函數的參數類型為string&&      e.static_cast顯式轉換類型為string&&   1.2.2傳入一個左值     a.推斷出_Tp的類型為string&     b.std::remove_reference<_Tp>::type的類型為string     c.move函數的返回類型為string&&     d.move函數的參數類型為string& &&,會折疊為string&         e.static_cast顯式轉換類型為string&&   1.3引用折疊       a.X& &,X& &&和X&& &都折疊為X&       b.X&& && 折疊為X&&   2.std::forward   2.1std::forward是如何定義的   復制代碼   /**    *  @brief  Forward an lvalue.    *  @return The parameter cast to the specified type.    *    *  This function is used to implement "perfect forwarding".    */   template<typename _Tp>     constexpr _Tp&&     forward(typename std::remove_reference<_Tp>::type& __t) noexcept     { return static_cast<_Tp&&>(__t); }     /**    *  @brief  Forward an rvalue.    *  @return The parameter cast to the specified type.    *    *  This function is used to implement "perfect forwarding".    */   template<typename _Tp>     constexpr _Tp&&     forward(typename std::remove_reference<_Tp>::type&& __t) noexcept     {       static_assert(!std::is_lvalue_reference<_Tp>::value, "template argument"             " substituting _Tp is an lvalue reference type");       return static_cast<_Tp&&>(__t);     } 復制代碼     2.2std::forward是如何工作的   2.2.1_Tp類型是左值引用   a.如果中轉函數的實參是左值string,_Tp的類型為string&,std::remove_reference<_Tp>::type為string   b.forward函數參數__t的類型折疊後為string&   c.string& && (_Tp&&)折疊後依舊為左值引用string&   d.forword函數的返回為string&   2.2.2_Tp類型是右值   a.如果中轉實參是右值sting,_Tp的類型為sting,std::remove_reference<_Tp>::type為string   b.forward函數參數__t的類型為string&&   c.forword函數的返回為string&&   2.3  模版重載   因為存在模版重載機制,所以左值使用第一個版本,而右值選擇第二個版本。       3.STL轉發的例子   復制代碼  // shared_ptr.h   // This constructor is non-standard, it is used by allocate_shared.   template<typename _Alloc, typename... _Args>     shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,            _Args&&... __args)     : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...)     { }     template<typename _Tp, typename _Alloc, typename... _Args>     inline shared_ptr<_Tp>     allocate_shared(const _Alloc& __a, _Args&&... __args)     {       return shared_ptr<_Tp>(_Sp_make_shared_tag(), __a,                  std::forward<_Args>(__args)...);     }     template<typename _Tp, typename... _Args>     inline shared_ptr<_Tp>     make_shared(_Args&&... __args)     {       typedef typename std::remove_const<_Tp>::type _Tp_nc;       return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),                        std::forward<_Args>(__args)...);     } 復制代碼         復制代碼 //shared_ptr_base.h #ifdef __GXX_RTTI     protected:       // This constructor is non-standard, it is used by allocate_shared.       template<typename _Alloc, typename... _Args>     __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,              _Args&&... __args)     : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,                 std::forward<_Args>(__args)...)     {       // _M_ptr needs to point to the newly constructed object.       // This relies on _Sp_counted_ptr_inplace::_M_get_deleter.       void* __p = _M_refcount._M_get_deleter(typeid(__tag));       _M_ptr = static_cast<_Tp*>(__p);       __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);     } #else       template<typename _Alloc>         struct _Deleter         {           void operator()(_Tp* __ptr)           {         typedef allocator_traits<_Alloc> _Alloc_traits;         _Alloc_traits::destroy(_M_alloc, __ptr);         _Alloc_traits::deallocate(_M_alloc, __ptr, 1);           }           _Alloc _M_alloc;         };         template<typename _Alloc, typename... _Args>     __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,              _Args&&... __args)     : _M_ptr(), _M_refcount()         {       typedef typename _Alloc::template rebind<_Tp>::other _Alloc2;           _Deleter<_Alloc2> __del = { _Alloc2(__a) };       typedef allocator_traits<_Alloc2> __traits;           _M_ptr = __traits::allocate(__del._M_alloc, 1);       __try         {           // _GLIBCXX_RESOLVE_LIB_DEFECTS           // 2070. allocate_shared should use allocator_traits<A>::construct           __traits::construct(__del._M_alloc, _M_ptr,                           std::forward<_Args>(__args)...);         }       __catch(...)         {           __traits::deallocate(__del._M_alloc, _M_ptr, 1);           __throw_exception_again;         }           __shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc);           _M_refcount._M_swap(__count);       __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);         } #endif 復制代碼     //new_allocator.h #if __cplusplus >= 201103L       template<typename _Up, typename... _Args>         void         construct(_Up* __p, _Args&&... __args)     { ::new((void *)__p) _Up(std::forward<_Args>(__args)...); } 上面STL例子,還應用了可變參數模版和轉發參數包語法,需要進一步了解。本人水平有限,如果錯誤請指正謝謝。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved