当前位置:   article > 正文

GNU C++ 智能指针16- 解析__shared_ptr类4_ptr4类型

ptr4类型

目录

一、关键点解析

1、_S_raw_ptr

2、__addressof

4、static_pointer_cast、const_pointer_cast和dynamic_pointer_cast

5、与bool类型的转换

6、与nullptr_t的比较

二、源码分析


一、关键点解析

1、_S_raw_ptr

  1. template<typename _Tp1>
  2. static _Tp1*
  3. _S_raw_ptr(_Tp1* __ptr)
  4. { return __ptr; }
  5. template<typename _Tp1>
  6. static auto
  7. _S_raw_ptr(_Tp1 __ptr) -> decltype(std::__addressof(*__ptr))
  8. { return std::__addressof(*__ptr); }

    对于C ++ 11,如果您想使用auto作为返回类型,则需要以这种方式描述有效的返回类型

auto funcName (args...) -> returnType

2、__addressof

  1. namespace std _GLIBCXX_VISIBILITY(default)
  2. {
  3. _GLIBCXX_BEGIN_NAMESPACE_VERSION
  4. // Used, in C++03 mode too, by allocators, etc.
  5. /**
  6. * @brief Same as C++11 std::addressof
  7. * @ingroup utilities
  8. */
  9. template<typename _Tp>
  10. inline _Tp*
  11. __addressof(_Tp& __r) _GLIBCXX_NOEXCEPT
  12. {
  13. return reinterpret_cast<_Tp*>
  14. (&const_cast<char&>(reinterpret_cast<const volatile char&>(__r)));
  15. }
  16. _GLIBCXX_END_NAMESPACE_VERSION
  17. } // namespace

__r的类型为__Tp
(1)将__r转为const volatile char&有几个作用
  (a)防止后面用&操作符获取地址时出发原类型(即__Tp)的重载操作(operator&).
  (b)reinterpret_cast操作符总是可以合法的在原类型的基础上加const或volatile, 但是如果__Tp原来带有const或volatile的话, 通过reinterpret_cast去掉是不允许的, 因此需要加上const volatile来避免编译器报错, 也就是不用在管__Tp是否是const或volatile了.
 (c)转换为char&, 因为换成其他类型有可能回触发强制地址对齐的操作, 这样的话真实地址就可能会改变, 造成Undefined Behavior.
(2)const_cast将const或volatile去掉. 因为后面我们要将获取的地址转换回__Tp*, 因为我们前面加了const, 所以这里我们再去掉。
(3)通过取地址符&获取地址后, 再通过reinterpret_cast转换回__Tp*(会保留__Tp的const或volatile如果它有这个修饰符的话)

3、operator==

  template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
    inline bool
    operator==(const __shared_ptr<_Tp1, _Lp>& __a,
           const __shared_ptr<_Tp2, _Lp>& __b) noexcept
    { return __a.get() == __b.get(); }

调用

      _Tp*
      get() const noexcept
      { return _M_ptr; }


       _Tp*              _M_ptr;         // Contained pointer.

       operator==还是比较包含的裸指针是否相等。

4、static_pointer_cast、const_pointer_cast和dynamic_pointer_cast

  1. // 20.7.2.2.9 shared_ptr casts
  2. // The seemingly equivalent code:
  3. // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
  4. // will eventually result in undefined behaviour, attempting to
  5. // delete the same object twice.
  6. /// static_pointer_cast
  7. template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
  8. inline __shared_ptr<_Tp, _Lp>
  9. static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
  10. { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); }
  11. // The seemingly equivalent code:
  12. // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
  13. // will eventually result in undefined behaviour, attempting to
  14. // delete the same object twice.
  15. /// const_pointer_cast
  16. template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
  17. inline __shared_ptr<_Tp, _Lp>
  18. const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
  19. { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); }
  20. // The seemingly equivalent code:
  21. // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
  22. // will eventually result in undefined behaviour, attempting to
  23. // delete the same object twice.
  24. /// dynamic_pointer_cast
  25. template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
  26. inline __shared_ptr<_Tp, _Lp>
  27. dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
  28. {
  29. if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
  30. return __shared_ptr<_Tp, _Lp>(__r, __p);
  31. return __shared_ptr<_Tp, _Lp>();
  32. }

       shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))这种代码会造成二次释放,产生未定义的结果,shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))和shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))也是一样的。所以提供了特殊版本static_pointer_cast、const_pointer_cast和dynamic_pointer_cast用来转换。

    语句return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get()))会调用下面的构造函数:

      template<typename _Tp1>
    __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p) noexcept
    : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
    { }

   _M_refcount(__r._M_refcount)会调用下面的构造函数:

  __shared_count(const __shared_count& __r) noexcept
      : _M_pi(__r._M_pi)
      {
    if (_M_pi != 0)
      _M_pi->_M_add_ref_copy();
      }

5、与bool类型的转换

  1. explicit operator bool() const // never throws
  2. { return _M_ptr == 0 ? false : true; }

   通过重载操作符与bool类型进行转换。

6、与nullptr_t的比较

  template<typename _Tp, _Lock_policy _Lp>
    inline bool
    operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
    { return !__a; }

     这个会调用到5中的内容,先转换到bool类型,然后再取反。
 

二、源码分析

  1. template<typename _Tp, _Lock_policy _Lp>
  2. class __shared_ptr
  3. {
  4. public:
  5. typedef _Tp element_type;// element_type即为_Tp类型
  6. constexpr __shared_ptr() noexcept//constexpr 构造函数
  7. : _M_ptr(0), _M_refcount()
  8. { }
  9. template<typename _Tp1>
  10. explicit __shared_ptr(_Tp1* __p)
  11. : _M_ptr(__p), _M_refcount(__p)
  12. {
  13. __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)//指针时可以赋值的
  14. static_assert( !is_void<_Tp1>::value, "incomplete type" );//不是void类型
  15. static_assert( sizeof(_Tp1) > 0, "incomplete type" );//类型大小大于0
  16. __enable_shared_from_this_helper(_M_refcount, __p, __p);//添加一个弱引用
  17. }
  18. template<typename _Tp1, typename _Deleter>
  19. __shared_ptr(_Tp1* __p, _Deleter __d)
  20. : _M_ptr(__p), _M_refcount(__p, __d)//构造函数
  21. {
  22. __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
  23. // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
  24. __enable_shared_from_this_helper(_M_refcount, __p, __p);
  25. }
  26. template<typename _Tp1, typename _Deleter, typename _Alloc>
  27. __shared_ptr(_Tp1* __p, _Deleter __d, _Alloc __a)//构造函数
  28. : _M_ptr(__p), _M_refcount(__p, __d, std::move(__a))
  29. {
  30. __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
  31. // TODO requires _Deleter CopyConstructible and __d(__p) well-formed
  32. __enable_shared_from_this_helper(_M_refcount, __p, __p);
  33. }
  34. template<typename _Deleter>
  35. __shared_ptr(nullptr_t __p, _Deleter __d)
  36. : _M_ptr(0), _M_refcount(__p, __d)
  37. { }
  38. template<typename _Deleter, typename _Alloc>
  39. __shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
  40. : _M_ptr(0), _M_refcount(__p, __d, std::move(__a))
  41. { }
  42. template<typename _Tp1>
  43. __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r, _Tp* __p) noexcept
  44. : _M_ptr(__p), _M_refcount(__r._M_refcount) // never throws
  45. { }
  46. __shared_ptr(const __shared_ptr&) noexcept = default;
  47. __shared_ptr& operator=(const __shared_ptr&) noexcept = default;
  48. ~__shared_ptr() = default;
  49. template<typename _Tp1, typename = typename
  50. std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
  51. __shared_ptr(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
  52. : _M_ptr(__r._M_ptr), _M_refcount(__r._M_refcount)
  53. { }
  54. __shared_ptr(__shared_ptr&& __r) noexcept//右值构造函数实现move语义
  55. : _M_ptr(__r._M_ptr), _M_refcount()
  56. {
  57. _M_refcount._M_swap(__r._M_refcount);//调用__shared_count类中的_M_swap
  58. __r._M_ptr = 0;
  59. }
  60. template<typename _Tp1, typename = typename
  61. std::enable_if<std::is_convertible<_Tp1*, _Tp*>::value>::type>
  62. __shared_ptr(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
  63. : _M_ptr(__r._M_ptr), _M_refcount()
  64. {
  65. _M_refcount._M_swap(__r._M_refcount);
  66. __r._M_ptr = 0;
  67. }
  68. template<typename _Tp1>
  69. explicit __shared_ptr(const __weak_ptr<_Tp1, _Lp>& __r)
  70. : _M_refcount(__r._M_refcount) // may throw
  71. {
  72. __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
  73. // It is now safe to copy __r._M_ptr, as
  74. // _M_refcount(__r._M_refcount) did not throw.
  75. _M_ptr = __r._M_ptr;
  76. }
  77. // If an exception is thrown this constructor has no effect.
  78. template<typename _Tp1, typename _Del>
  79. __shared_ptr(std::unique_ptr<_Tp1, _Del>&& __r)
  80. : _M_ptr(__r.get()), _M_refcount()
  81. {
  82. __glibcxx_function_requires(_ConvertibleConcept<_Tp1*, _Tp*>)
  83. auto __raw = _S_raw_ptr(__r.get());
  84. _M_refcount = __shared_count<_Lp>(std::move(__r));
  85. __enable_shared_from_this_helper(_M_refcount, __raw, __raw);
  86. }
  87. #if _GLIBCXX_USE_DEPRECATED
  88. // Postcondition: use_count() == 1 and __r.get() == 0
  89. template<typename _Tp1>
  90. __shared_ptr(std::auto_ptr<_Tp1>&& __r);
  91. #endif
  92. /* TODO: use delegating constructor */
  93. constexpr __shared_ptr(nullptr_t) noexcept
  94. : _M_ptr(0), _M_refcount()
  95. { }
  96. template<typename _Tp1>
  97. __shared_ptr&
  98. operator=(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
  99. {
  100. _M_ptr = __r._M_ptr;
  101. _M_refcount = __r._M_refcount; // __shared_count::op= doesn't throw
  102. return *this;
  103. }
  104. #if _GLIBCXX_USE_DEPRECATED
  105. template<typename _Tp1>
  106. __shared_ptr&
  107. operator=(std::auto_ptr<_Tp1>&& __r)
  108. {
  109. __shared_ptr(std::move(__r)).swap(*this);
  110. return *this;
  111. }
  112. #endif
  113. __shared_ptr&
  114. operator=(__shared_ptr&& __r) noexcept
  115. {
  116. __shared_ptr(std::move(__r)).swap(*this);
  117. return *this;
  118. }
  119. template<class _Tp1>
  120. __shared_ptr&
  121. operator=(__shared_ptr<_Tp1, _Lp>&& __r) noexcept
  122. {
  123. __shared_ptr(std::move(__r)).swap(*this);
  124. return *this;
  125. }
  126. template<typename _Tp1, typename _Del>
  127. __shared_ptr&
  128. operator=(std::unique_ptr<_Tp1, _Del>&& __r)
  129. {
  130. __shared_ptr(std::move(__r)).swap(*this);
  131. return *this;
  132. }
  133. void
  134. reset() noexcept
  135. { __shared_ptr().swap(*this); }
  136. template<typename _Tp1>
  137. void
  138. reset(_Tp1* __p) // _Tp1 must be complete.
  139. {
  140. // Catch self-reset errors.
  141. _GLIBCXX_DEBUG_ASSERT(__p == 0 || __p != _M_ptr);
  142. __shared_ptr(__p).swap(*this);
  143. }
  144. template<typename _Tp1, typename _Deleter>
  145. void
  146. reset(_Tp1* __p, _Deleter __d)
  147. { __shared_ptr(__p, __d).swap(*this); }
  148. template<typename _Tp1, typename _Deleter, typename _Alloc>
  149. void
  150. reset(_Tp1* __p, _Deleter __d, _Alloc __a)
  151. { __shared_ptr(__p, __d, std::move(__a)).swap(*this); }
  152. // Allow class instantiation when _Tp is [cv-qual] void.
  153. typename std::add_lvalue_reference<_Tp>::type
  154. operator*() const noexcept
  155. {
  156. _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
  157. return *_M_ptr;
  158. }
  159. _Tp*
  160. operator->() const noexcept
  161. {
  162. _GLIBCXX_DEBUG_ASSERT(_M_ptr != 0);
  163. return _M_ptr;
  164. }
  165. _Tp*
  166. get() const noexcept
  167. { return _M_ptr; }
  168. explicit operator bool() const // never throws
  169. { return _M_ptr == 0 ? false : true; }
  170. bool
  171. unique() const noexcept
  172. { return _M_refcount._M_unique(); }
  173. long
  174. use_count() const noexcept
  175. { return _M_refcount._M_get_use_count(); }
  176. void
  177. swap(__shared_ptr<_Tp, _Lp>& __other) noexcept
  178. {
  179. std::swap(_M_ptr, __other._M_ptr);
  180. _M_refcount._M_swap(__other._M_refcount);
  181. }
  182. template<typename _Tp1>
  183. bool
  184. owner_before(__shared_ptr<_Tp1, _Lp> const& __rhs) const
  185. { return _M_refcount._M_less(__rhs._M_refcount); }
  186. template<typename _Tp1>
  187. bool
  188. owner_before(__weak_ptr<_Tp1, _Lp> const& __rhs) const
  189. { return _M_refcount._M_less(__rhs._M_refcount); }
  190. #ifdef __GXX_RTTI
  191. protected:
  192. // This constructor is non-standard, it is used by allocate_shared.
  193. template<typename _Alloc, typename... _Args>
  194. __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
  195. _Args&&... __args)
  196. : _M_ptr(), _M_refcount(__tag, (_Tp*)0, __a,
  197. std::forward<_Args>(__args)...)
  198. {
  199. // _M_ptr needs to point to the newly constructed object.
  200. // This relies on _Sp_counted_ptr_inplace::_M_get_deleter.
  201. void* __p = _M_refcount._M_get_deleter(typeid(__tag));
  202. _M_ptr = static_cast<_Tp*>(__p);
  203. __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
  204. }
  205. #else
  206. template<typename _Alloc>
  207. struct _Deleter
  208. {
  209. void operator()(_Tp* __ptr)
  210. {
  211. typedef allocator_traits<_Alloc> _Alloc_traits;
  212. _Alloc_traits::destroy(_M_alloc, __ptr);
  213. _Alloc_traits::deallocate(_M_alloc, __ptr, 1);
  214. }
  215. _Alloc _M_alloc;
  216. };
  217. template<typename _Alloc, typename... _Args>
  218. __shared_ptr(_Sp_make_shared_tag __tag, const _Alloc& __a,
  219. _Args&&... __args)
  220. : _M_ptr(), _M_refcount()
  221. {
  222. typedef typename _Alloc::template rebind<_Tp>::other _Alloc2;
  223. _Deleter<_Alloc2> __del = { _Alloc2(__a) };
  224. typedef allocator_traits<_Alloc2> __traits;
  225. _M_ptr = __traits::allocate(__del._M_alloc, 1);
  226. __try
  227. {
  228. // _GLIBCXX_RESOLVE_LIB_DEFECTS
  229. // 2070. allocate_shared should use allocator_traits<A>::construct
  230. __traits::construct(__del._M_alloc, _M_ptr,
  231. std::forward<_Args>(__args)...);
  232. }
  233. __catch(...)
  234. {
  235. __traits::deallocate(__del._M_alloc, _M_ptr, 1);
  236. __throw_exception_again;
  237. }
  238. __shared_count<_Lp> __count(_M_ptr, __del, __del._M_alloc);
  239. _M_refcount._M_swap(__count);
  240. __enable_shared_from_this_helper(_M_refcount, _M_ptr, _M_ptr);
  241. }
  242. #endif
  243. template<typename _Tp1, _Lock_policy _Lp1, typename _Alloc,
  244. typename... _Args>
  245. friend __shared_ptr<_Tp1, _Lp1>
  246. __allocate_shared(const _Alloc& __a, _Args&&... __args);
  247. // This constructor is used by __weak_ptr::lock() and
  248. // shared_ptr::shared_ptr(const weak_ptr&, std::nothrow_t).
  249. __shared_ptr(const __weak_ptr<_Tp, _Lp>& __r, std::nothrow_t)
  250. : _M_refcount(__r._M_refcount, std::nothrow)
  251. {
  252. _M_ptr = _M_refcount._M_get_use_count() ? __r._M_ptr : nullptr;
  253. }
  254. friend class __weak_ptr<_Tp, _Lp>;
  255. private:
  256. void*
  257. _M_get_deleter(const std::type_info& __ti) const noexcept
  258. { return _M_refcount._M_get_deleter(__ti); }
  259. template<typename _Tp1>
  260. static _Tp1*
  261. _S_raw_ptr(_Tp1* __ptr)
  262. { return __ptr; }
  263. template<typename _Tp1>
  264. static auto
  265. _S_raw_ptr(_Tp1 __ptr) -> decltype(std::__addressof(*__ptr))
  266. { return std::__addressof(*__ptr); }
  267. template<typename _Tp1, _Lock_policy _Lp1> friend class __shared_ptr;
  268. template<typename _Tp1, _Lock_policy _Lp1> friend class __weak_ptr;
  269. template<typename _Del, typename _Tp1, _Lock_policy _Lp1>
  270. friend _Del* get_deleter(const __shared_ptr<_Tp1, _Lp1>&) noexcept;
  271. _Tp* _M_ptr; // Contained pointer.
  272. __shared_count<_Lp> _M_refcount; // Reference counter.
  273. };
  274. // 20.7.2.2.7 shared_ptr comparisons
  275. template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
  276. inline bool
  277. operator==(const __shared_ptr<_Tp1, _Lp>& __a,
  278. const __shared_ptr<_Tp2, _Lp>& __b) noexcept
  279. { return __a.get() == __b.get(); }
  280. template<typename _Tp, _Lock_policy _Lp>
  281. inline bool
  282. operator==(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
  283. { return !__a; }
  284. template<typename _Tp, _Lock_policy _Lp>
  285. inline bool
  286. operator==(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
  287. { return !__a; }
  288. template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
  289. inline bool
  290. operator!=(const __shared_ptr<_Tp1, _Lp>& __a,
  291. const __shared_ptr<_Tp2, _Lp>& __b) noexcept
  292. { return __a.get() != __b.get(); }
  293. template<typename _Tp, _Lock_policy _Lp>
  294. inline bool
  295. operator!=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
  296. { return (bool)__a; }
  297. template<typename _Tp, _Lock_policy _Lp>
  298. inline bool
  299. operator!=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
  300. { return (bool)__a; }
  301. template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
  302. inline bool
  303. operator<(const __shared_ptr<_Tp1, _Lp>& __a,
  304. const __shared_ptr<_Tp2, _Lp>& __b) noexcept
  305. {
  306. typedef typename std::common_type<_Tp1*, _Tp2*>::type _CT;
  307. return std::less<_CT>()(__a.get(), __b.get());
  308. }
  309. template<typename _Tp, _Lock_policy _Lp>
  310. inline bool
  311. operator<(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
  312. { return std::less<_Tp*>()(__a.get(), nullptr); }
  313. template<typename _Tp, _Lock_policy _Lp>
  314. inline bool
  315. operator<(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
  316. { return std::less<_Tp*>()(nullptr, __a.get()); }
  317. template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
  318. inline bool
  319. operator<=(const __shared_ptr<_Tp1, _Lp>& __a,
  320. const __shared_ptr<_Tp2, _Lp>& __b) noexcept
  321. { return !(__b < __a); }
  322. template<typename _Tp, _Lock_policy _Lp>
  323. inline bool
  324. operator<=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
  325. { return !(nullptr < __a); }
  326. template<typename _Tp, _Lock_policy _Lp>
  327. inline bool
  328. operator<=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
  329. { return !(__a < nullptr); }
  330. template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
  331. inline bool
  332. operator>(const __shared_ptr<_Tp1, _Lp>& __a,
  333. const __shared_ptr<_Tp2, _Lp>& __b) noexcept
  334. { return (__b < __a); }
  335. template<typename _Tp, _Lock_policy _Lp>
  336. inline bool
  337. operator>(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
  338. { return std::less<_Tp*>()(nullptr, __a.get()); }
  339. template<typename _Tp, _Lock_policy _Lp>
  340. inline bool
  341. operator>(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
  342. { return std::less<_Tp*>()(__a.get(), nullptr); }
  343. template<typename _Tp1, typename _Tp2, _Lock_policy _Lp>
  344. inline bool
  345. operator>=(const __shared_ptr<_Tp1, _Lp>& __a,
  346. const __shared_ptr<_Tp2, _Lp>& __b) noexcept
  347. { return !(__a < __b); }
  348. template<typename _Tp, _Lock_policy _Lp>
  349. inline bool
  350. operator>=(const __shared_ptr<_Tp, _Lp>& __a, nullptr_t) noexcept
  351. { return !(__a < nullptr); }
  352. template<typename _Tp, _Lock_policy _Lp>
  353. inline bool
  354. operator>=(nullptr_t, const __shared_ptr<_Tp, _Lp>& __a) noexcept
  355. { return !(nullptr < __a); }
  356. template<typename _Sp>
  357. struct _Sp_less : public binary_function<_Sp, _Sp, bool>
  358. {
  359. bool
  360. operator()(const _Sp& __lhs, const _Sp& __rhs) const noexcept
  361. {
  362. typedef typename _Sp::element_type element_type;
  363. return std::less<element_type*>()(__lhs.get(), __rhs.get());
  364. }
  365. };
  366. template<typename _Tp, _Lock_policy _Lp>
  367. struct less<__shared_ptr<_Tp, _Lp>>
  368. : public _Sp_less<__shared_ptr<_Tp, _Lp>>
  369. { };
  370. // 20.7.2.2.8 shared_ptr specialized algorithms.
  371. template<typename _Tp, _Lock_policy _Lp>
  372. inline void
  373. swap(__shared_ptr<_Tp, _Lp>& __a, __shared_ptr<_Tp, _Lp>& __b) noexcept
  374. { __a.swap(__b); }
  375. // 20.7.2.2.9 shared_ptr casts
  376. // The seemingly equivalent code:
  377. // shared_ptr<_Tp, _Lp>(static_cast<_Tp*>(__r.get()))
  378. // will eventually result in undefined behaviour, attempting to
  379. // delete the same object twice.
  380. /// static_pointer_cast
  381. template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
  382. inline __shared_ptr<_Tp, _Lp>
  383. static_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
  384. { return __shared_ptr<_Tp, _Lp>(__r, static_cast<_Tp*>(__r.get())); }
  385. // The seemingly equivalent code:
  386. // shared_ptr<_Tp, _Lp>(const_cast<_Tp*>(__r.get()))
  387. // will eventually result in undefined behaviour, attempting to
  388. // delete the same object twice.
  389. /// const_pointer_cast
  390. template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
  391. inline __shared_ptr<_Tp, _Lp>
  392. const_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
  393. { return __shared_ptr<_Tp, _Lp>(__r, const_cast<_Tp*>(__r.get())); }
  394. // The seemingly equivalent code:
  395. // shared_ptr<_Tp, _Lp>(dynamic_cast<_Tp*>(__r.get()))
  396. // will eventually result in undefined behaviour, attempting to
  397. // delete the same object twice.
  398. /// dynamic_pointer_cast
  399. template<typename _Tp, typename _Tp1, _Lock_policy _Lp>
  400. inline __shared_ptr<_Tp, _Lp>
  401. dynamic_pointer_cast(const __shared_ptr<_Tp1, _Lp>& __r) noexcept
  402. {
  403. if (_Tp* __p = dynamic_cast<_Tp*>(__r.get()))
  404. return __shared_ptr<_Tp, _Lp>(__r, __p);
  405. return __shared_ptr<_Tp, _Lp>();
  406. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/喵喵爱编程/article/detail/999984
推荐阅读
相关标签
  

闽ICP备14008679号