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

2015-01-27 06:10:51 · 作者: · 浏览: 9
1.std::move
?
1.1std::move是如何定义的
?
? template
? ? constexpr typename std::remove_reference<_Tp>::type&&
? ? move(_Tp&& __t) noexcept
? ? { return static_cast::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
? ? 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
? ? 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
? ? shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
? ? ? ? ? ?_Args&&... __args)
? ? : __shared_ptr<_Tp>(__tag, __a, std::forward<_Args>(__args)...)
? ? { }
?
  template
? ? 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
? ? 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
? ? __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_ge