From Jason Turner

[util.smartptr]

Diff to HTML by rtfpessoa

Files changed (1) hide show
  1. tmp/tmppbpvy1z8/{from.md → to.md} +66 -34
tmp/tmppbpvy1z8/{from.md → to.md} RENAMED
@@ -37,12 +37,12 @@ namespace std {
37
  // [util.smartptr.shared.const], constructors:
38
  constexpr shared_ptr() noexcept;
39
  template<class Y> explicit shared_ptr(Y* p);
40
  template<class Y, class D> shared_ptr(Y* p, D d);
41
  template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
42
- template <class D> shared_ptr(nullptr_t p, D d)
43
- template <class D, class A> shared_ptr(nullptr_t p, D d, A a)
44
  template<class Y> shared_ptr(const shared_ptr<Y>& r, T* p) noexcept;
45
  shared_ptr(const shared_ptr& r) noexcept;
46
  template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
47
  shared_ptr(shared_ptr&& r) noexcept;
48
  template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
@@ -169,11 +169,11 @@ races.
169
  constexpr shared_ptr() noexcept;
170
  ```
171
 
172
  *Effects:* Constructs an *empty* `shared_ptr` object.
173
 
174
- *Postconditions:* `use_count() == 0 && get() == 0`.
175
 
176
  ``` cpp
177
  template<class Y> explicit shared_ptr(Y* p);
178
  ```
179
 
@@ -227,19 +227,19 @@ template<class Y> shared_ptr(const shared_ptr<Y>& r, T *p) noexcept;
227
  To avoid the possibility of a dangling pointer, the user of this
228
  constructor must ensure that `p` remains valid at least until the
229
  ownership group of `r` is destroyed.
230
 
231
  This constructor allows creation of an *empty* `shared_ptr` instance
232
- with a non-NULL stored pointer.
233
 
234
  ``` cpp
235
  shared_ptr(const shared_ptr& r) noexcept;
236
  template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
237
  ```
238
 
239
- *Requires:* The second constructor shall not participate in the overload
240
- resolution unless `Y*` is implicitly convertible to `T*`.
241
 
242
  *Effects:* If `r` is *empty*, constructs an *empty* `shared_ptr` object;
243
  otherwise, constructs a `shared_ptr` object that *shares ownership* with
244
  `r`.
245
 
@@ -254,11 +254,11 @@ The second constructor shall not participate in overload resolution
254
  unless `Y*` is convertible to `T*`.
255
 
256
  *Effects:* Move-constructs a `shared_ptr` instance from `r`.
257
 
258
  *Postconditions:* `*this` shall contain the old value of `r`. `r` shall
259
- be *empty*. `r.get() == 0.`
260
 
261
  ``` cpp
262
  template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
263
  ```
264
 
@@ -282,11 +282,11 @@ complete type. The expression `delete r.release()` shall be well formed,
282
  shall have well defined behavior, and shall not throw exceptions.
283
 
284
  *Effects:* Constructs a `shared_ptr` object that stores and *owns*
285
  `r.release()`.
286
 
287
- *Postconditions:* `use_count() == 1` `&&` `r.get() == 0`.
288
 
289
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
290
  resource other than memory could not be obtained.
291
 
292
  If an exception is thrown, the constructor has no effect.
@@ -439,11 +439,11 @@ bool unique() const noexcept;
439
 
440
  *Returns:* `use_count() == 1`.
441
 
442
  `unique()` may be faster than `use_count()`. If you are using `unique()`
443
  to implement copy on write, do not rely on a specific value when
444
- `get() == 0`.
445
 
446
  ``` cpp
447
  explicit operator bool() const noexcept;
448
  ```
449
 
@@ -489,13 +489,13 @@ the newly constructed object of type `T`.
489
  *Postconditions:* `get() != 0 && use_count() == 1`
490
 
491
  *Throws:* `bad_alloc`, or an exception thrown from `A::allocate` or from
492
  the constructor of `T`.
493
 
494
- *Remarks:* Implementations are encouraged, but not required, to perform
495
- no more than one memory allocation. This provides efficiency equivalent
496
- to an intrusive smart pointer.
497
 
498
  These functions will typically allocate more memory than `sizeof(T)` to
499
  allow for internal bookkeeping structures such as the reference counts.
500
 
501
  ##### `shared_ptr` comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
@@ -509,11 +509,11 @@ template<class T, class U> bool operator==(const shared_ptr<T>& a, const shared_
509
  ``` cpp
510
  template<class T, class U> bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
511
  ```
512
 
513
  *Returns:* `less<V>()(a.get(), b.get())`, where `V` is the composite
514
- pointer type ([[expr.rel]]) of `T*` and `U*`.
515
 
516
  Defining a comparison operator allows `shared_ptr` objects to be used as
517
  keys in associative containers.
518
 
519
  ``` cpp
@@ -646,14 +646,14 @@ undefined behavior, attempting to delete the same object twice.
646
  ``` cpp
647
  template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept;
648
  ```
649
 
650
  *Returns:* If `p` *owns* a deleter `d` of type cv-unqualified `D`,
651
- returns `&d`; otherwise returns `0`. The returned pointer remains valid
652
- as long as there exists a `shared_ptr` instance that owns `d`. It is
653
- unspecified whether the pointer remains valid longer than that. This can
654
- happen if the implementation doesn’t destroy the deleter until all
655
  `weak_ptr` instances that share ownership with `p` have been destroyed.
656
 
657
  ##### `shared_ptr` I/O <a id="util.smartptr.shared.io">[[util.smartptr.shared.io]]</a>
658
 
659
  ``` cpp
@@ -680,29 +680,33 @@ namespace std {
680
  // [util.smartptr.weak.const], constructors
681
  constexpr weak_ptr() noexcept;
682
  template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;
683
  weak_ptr(weak_ptr const& r) noexcept;
684
  template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;
 
 
685
 
686
  // [util.smartptr.weak.dest], destructor
687
  ~weak_ptr();
688
 
689
  // [util.smartptr.weak.assign], assignment
690
  weak_ptr& operator=(weak_ptr const& r) noexcept;
691
  template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;
692
  template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;
 
 
693
 
694
  // [util.smartptr.weak.mod], modifiers
695
  void swap(weak_ptr& r) noexcept;
696
  void reset() noexcept;
697
 
698
  // [util.smartptr.weak.obs], observers
699
  long use_count() const noexcept;
700
  bool expired() const noexcept;
701
  shared_ptr<T> lock() const noexcept;
702
- template<class U> bool owner_before(shared_ptr<U> const& b);
703
- template<class U> bool owner_before(weak_ptr<U> const& b);
704
  };
705
 
706
  // [util.smartptr.weak.spec], specialized algorithms
707
  template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
708
  } // namespace std
@@ -726,19 +730,32 @@ constexpr weak_ptr() noexcept;
726
  weak_ptr(const weak_ptr& r) noexcept;
727
  template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept;
728
  template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
729
  ```
730
 
731
- *Requires:* The second and third constructors shall not participate in
732
- the overload resolution unless `Y*` is implicitly convertible to `T*`.
733
 
734
  *Effects:* If `r` is *empty*, constructs an *empty* `weak_ptr` object;
735
  otherwise, constructs a `weak_ptr` object that *shares ownership* with
736
  `r` and stores a copy of the pointer stored in `r`.
737
 
738
  *Postconditions:* `use_count() == r.use_count()`.
739
 
 
 
 
 
 
 
 
 
 
 
 
 
 
740
  ##### `weak_ptr` destructor <a id="util.smartptr.weak.dest">[[util.smartptr.weak.dest]]</a>
741
 
742
  ``` cpp
743
  ~weak_ptr();
744
  ```
@@ -757,10 +774,21 @@ template<class Y> weak_ptr& operator=(const shared_ptr<Y>& r) noexcept;
757
  *Effects:* Equivalent to `weak_ptr(r).swap(*this)`.
758
 
759
  *Remarks:* The implementation may meet the effects (and the implied
760
  guarantees) via different means, without creating a temporary.
761
 
 
 
 
 
 
 
 
 
 
 
 
762
  ##### `weak_ptr` modifiers <a id="util.smartptr.weak.mod">[[util.smartptr.weak.mod]]</a>
763
 
764
  ``` cpp
765
  void swap(weak_ptr& r) noexcept;
766
  ```
@@ -794,15 +822,16 @@ bool expired() const noexcept;
794
 
795
  ``` cpp
796
  shared_ptr<T> lock() const noexcept;
797
  ```
798
 
799
- *Returns:* `expired() ? shared_ptr<T>() : shared_ptr<T>(*this)`.
 
800
 
801
  ``` cpp
802
- template<class U> bool owner_before(shared_ptr<U> const& b);
803
- template<class U> bool owner_before(weak_ptr<U> const& b);
804
  ```
805
 
806
  *Returns:* An unspecified value such that
807
 
808
  - `x.owner_before(y)` defines a strict weak ordering as defined
@@ -818,11 +847,11 @@ template<class U> bool owner_before(weak_ptr<U> const& b);
818
  template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
819
  ```
820
 
821
  *Effects:* Equivalent to `a.swap(b)`.
822
 
823
- ##### Class template `owner_less` <a id="util.smartptr.ownerless">[[util.smartptr.ownerless]]</a>
824
 
825
  The class template `owner_less` allows ownership-based mixed comparisons
826
  of shared and weak pointers.
827
 
828
  ``` cpp
@@ -1049,11 +1078,11 @@ template<class T>
1049
  template<class T>
1050
  bool atomic_compare_exchange_weak(
1051
  shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
1052
  ```
1053
 
1054
- *Requires:* `p` shall not be null.
1055
 
1056
  *Returns:*
1057
  `atomic_compare_exchange_weak_explicit(p, v, w, memory_order_seq_cst, memory_order_seq_cst)`.
1058
 
1059
  *Throws:* Nothing.
@@ -1076,11 +1105,11 @@ template<class T>
1076
  bool atomic_compare_exchange_strong_explicit(
1077
  shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
1078
  memory_order success, memory_order failure);
1079
  ```
1080
 
1081
- *Requires:* `p` shall not be null.
1082
 
1083
  *Requires:* `failure` shall not be `memory_order_release`,
1084
  `memory_order_acq_rel`, or stronger than `success`.
1085
 
1086
  *Effects:* If `*p` is equivalent to `*v`, assigns `w` to `*p` and has
@@ -1102,20 +1131,23 @@ See  [[atomics.types.operations]].
1102
 
1103
  ``` cpp
1104
  template <class T, class D> struct hash<unique_ptr<T, D> >;
1105
  ```
1106
 
1107
- *Requires:* The template specialization shall meet the requirements of
1108
- class template `hash` ([[unord.hash]]). For an object `p` of type `UP`,
1109
- where `UP` is `unique_ptr<T, D>`, `hash<UP>()(p)` shall evaluate to the
1110
- same value as `hash<typename UP::pointer>()(p.get())`. The
1111
- specialization `hash<typename UP::pointer>` shall be well-formed.
 
 
 
1112
 
1113
  ``` cpp
1114
  template <class T> struct hash<shared_ptr<T> >;
1115
  ```
1116
 
1117
- *Requires:* The template specialization shall meet the requirements of
1118
- class template `hash` ([[unord.hash]]). For an object `p` of type
1119
  `shared_ptr<T>`, `hash<shared_ptr<T> >()(p)` shall evaluate to the same
1120
  value as `hash<T*>()(p.get())`.
1121
 
 
37
  // [util.smartptr.shared.const], constructors:
38
  constexpr shared_ptr() noexcept;
39
  template<class Y> explicit shared_ptr(Y* p);
40
  template<class Y, class D> shared_ptr(Y* p, D d);
41
  template<class Y, class D, class A> shared_ptr(Y* p, D d, A a);
42
+ template <class D> shared_ptr(nullptr_t p, D d);
43
+ template <class D, class A> shared_ptr(nullptr_t p, D d, A a);
44
  template<class Y> shared_ptr(const shared_ptr<Y>& r, T* p) noexcept;
45
  shared_ptr(const shared_ptr& r) noexcept;
46
  template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
47
  shared_ptr(shared_ptr&& r) noexcept;
48
  template<class Y> shared_ptr(shared_ptr<Y>&& r) noexcept;
 
169
  constexpr shared_ptr() noexcept;
170
  ```
171
 
172
  *Effects:* Constructs an *empty* `shared_ptr` object.
173
 
174
+ *Postconditions:* `use_count() == 0 && get() == nullptr`.
175
 
176
  ``` cpp
177
  template<class Y> explicit shared_ptr(Y* p);
178
  ```
179
 
 
227
  To avoid the possibility of a dangling pointer, the user of this
228
  constructor must ensure that `p` remains valid at least until the
229
  ownership group of `r` is destroyed.
230
 
231
  This constructor allows creation of an *empty* `shared_ptr` instance
232
+ with a non-null stored pointer.
233
 
234
  ``` cpp
235
  shared_ptr(const shared_ptr& r) noexcept;
236
  template<class Y> shared_ptr(const shared_ptr<Y>& r) noexcept;
237
  ```
238
 
239
+ The second constructor shall not participate in overload resolution
240
+ unless `Y*` is implicitly convertible to `T*`.
241
 
242
  *Effects:* If `r` is *empty*, constructs an *empty* `shared_ptr` object;
243
  otherwise, constructs a `shared_ptr` object that *shares ownership* with
244
  `r`.
245
 
 
254
  unless `Y*` is convertible to `T*`.
255
 
256
  *Effects:* Move-constructs a `shared_ptr` instance from `r`.
257
 
258
  *Postconditions:* `*this` shall contain the old value of `r`. `r` shall
259
+ be *empty*. `r.get() == nullptr.`
260
 
261
  ``` cpp
262
  template<class Y> explicit shared_ptr(const weak_ptr<Y>& r);
263
  ```
264
 
 
282
  shall have well defined behavior, and shall not throw exceptions.
283
 
284
  *Effects:* Constructs a `shared_ptr` object that stores and *owns*
285
  `r.release()`.
286
 
287
+ *Postconditions:* `use_count() == 1` `&&` `r.get() == nullptr`.
288
 
289
  *Throws:* `bad_alloc`, or an *implementation-defined* exception when a
290
  resource other than memory could not be obtained.
291
 
292
  If an exception is thrown, the constructor has no effect.
 
439
 
440
  *Returns:* `use_count() == 1`.
441
 
442
  `unique()` may be faster than `use_count()`. If you are using `unique()`
443
  to implement copy on write, do not rely on a specific value when
444
+ `get() == nullptr`.
445
 
446
  ``` cpp
447
  explicit operator bool() const noexcept;
448
  ```
449
 
 
489
  *Postconditions:* `get() != 0 && use_count() == 1`
490
 
491
  *Throws:* `bad_alloc`, or an exception thrown from `A::allocate` or from
492
  the constructor of `T`.
493
 
494
+ *Remarks:* Implementations should perform no more than one memory
495
+ allocation. This provides efficiency equivalent to an intrusive smart
496
+ pointer.
497
 
498
  These functions will typically allocate more memory than `sizeof(T)` to
499
  allow for internal bookkeeping structures such as the reference counts.
500
 
501
  ##### `shared_ptr` comparison <a id="util.smartptr.shared.cmp">[[util.smartptr.shared.cmp]]</a>
 
509
  ``` cpp
510
  template<class T, class U> bool operator<(const shared_ptr<T>& a, const shared_ptr<U>& b) noexcept;
511
  ```
512
 
513
  *Returns:* `less<V>()(a.get(), b.get())`, where `V` is the composite
514
+ pointer type (Clause  [[expr]]) of `T*` and `U*`.
515
 
516
  Defining a comparison operator allows `shared_ptr` objects to be used as
517
  keys in associative containers.
518
 
519
  ``` cpp
 
646
  ``` cpp
647
  template<class D, class T> D* get_deleter(const shared_ptr<T>& p) noexcept;
648
  ```
649
 
650
  *Returns:* If `p` *owns* a deleter `d` of type cv-unqualified `D`,
651
+ returns `&d`; otherwise returns `nullptr`. The returned pointer remains
652
+ valid as long as there exists a `shared_ptr` instance that owns `d`. It
653
+ is unspecified whether the pointer remains valid longer than that. This
654
+ can happen if the implementation doesn’t destroy the deleter until all
655
  `weak_ptr` instances that share ownership with `p` have been destroyed.
656
 
657
  ##### `shared_ptr` I/O <a id="util.smartptr.shared.io">[[util.smartptr.shared.io]]</a>
658
 
659
  ``` cpp
 
680
  // [util.smartptr.weak.const], constructors
681
  constexpr weak_ptr() noexcept;
682
  template<class Y> weak_ptr(shared_ptr<Y> const& r) noexcept;
683
  weak_ptr(weak_ptr const& r) noexcept;
684
  template<class Y> weak_ptr(weak_ptr<Y> const& r) noexcept;
685
+ weak_ptr(weak_ptr&& r) noexcept;
686
+ template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
687
 
688
  // [util.smartptr.weak.dest], destructor
689
  ~weak_ptr();
690
 
691
  // [util.smartptr.weak.assign], assignment
692
  weak_ptr& operator=(weak_ptr const& r) noexcept;
693
  template<class Y> weak_ptr& operator=(weak_ptr<Y> const& r) noexcept;
694
  template<class Y> weak_ptr& operator=(shared_ptr<Y> const& r) noexcept;
695
+ weak_ptr& operator=(weak_ptr&& r) noexcept;
696
+ template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
697
 
698
  // [util.smartptr.weak.mod], modifiers
699
  void swap(weak_ptr& r) noexcept;
700
  void reset() noexcept;
701
 
702
  // [util.smartptr.weak.obs], observers
703
  long use_count() const noexcept;
704
  bool expired() const noexcept;
705
  shared_ptr<T> lock() const noexcept;
706
+ template<class U> bool owner_before(shared_ptr<U> const& b) const;
707
+ template<class U> bool owner_before(weak_ptr<U> const& b) const;
708
  };
709
 
710
  // [util.smartptr.weak.spec], specialized algorithms
711
  template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
712
  } // namespace std
 
730
  weak_ptr(const weak_ptr& r) noexcept;
731
  template<class Y> weak_ptr(const weak_ptr<Y>& r) noexcept;
732
  template<class Y> weak_ptr(const shared_ptr<Y>& r) noexcept;
733
  ```
734
 
735
+ The second and third constructors shall not participate in overload
736
+ resolution unless `Y*` is implicitly convertible to `T*`.
737
 
738
  *Effects:* If `r` is *empty*, constructs an *empty* `weak_ptr` object;
739
  otherwise, constructs a `weak_ptr` object that *shares ownership* with
740
  `r` and stores a copy of the pointer stored in `r`.
741
 
742
  *Postconditions:* `use_count() == r.use_count()`.
743
 
744
+ ``` cpp
745
+ weak_ptr(weak_ptr&& r) noexcept;
746
+ template<class Y> weak_ptr(weak_ptr<Y>&& r) noexcept;
747
+ ```
748
+
749
+ The second constructor shall not participate in overload resolution
750
+ unless `Y*` is implicitly convertible to `T*`.
751
+
752
+ *Effects:* Move-constructs a `weak_ptr` instance from `r`.
753
+
754
+ *Postconditions:* `*this` shall contain the old value of `r`. `r` shall
755
+ be *empty*. `r.use_count() == 0`.
756
+
757
  ##### `weak_ptr` destructor <a id="util.smartptr.weak.dest">[[util.smartptr.weak.dest]]</a>
758
 
759
  ``` cpp
760
  ~weak_ptr();
761
  ```
 
774
  *Effects:* Equivalent to `weak_ptr(r).swap(*this)`.
775
 
776
  *Remarks:* The implementation may meet the effects (and the implied
777
  guarantees) via different means, without creating a temporary.
778
 
779
+ *Returns:* `*this`.
780
+
781
+ ``` cpp
782
+ weak_ptr& operator=(weak_ptr&& r) noexcept;
783
+ template<class Y> weak_ptr& operator=(weak_ptr<Y>&& r) noexcept;
784
+ ```
785
+
786
+ *Effects:* Equivalent to `weak_ptr(std::move(r)).swap(*this)`.
787
+
788
+ *Returns:* `*this`.
789
+
790
  ##### `weak_ptr` modifiers <a id="util.smartptr.weak.mod">[[util.smartptr.weak.mod]]</a>
791
 
792
  ``` cpp
793
  void swap(weak_ptr& r) noexcept;
794
  ```
 
822
 
823
  ``` cpp
824
  shared_ptr<T> lock() const noexcept;
825
  ```
826
 
827
+ *Returns:* `expired() ? shared_ptr<T>() : shared_ptr<T>(*this)`,
828
+ executed atomically.
829
 
830
  ``` cpp
831
+ template<class U> bool owner_before(shared_ptr<U> const& b) const;
832
+ template<class U> bool owner_before(weak_ptr<U> const& b) const;
833
  ```
834
 
835
  *Returns:* An unspecified value such that
836
 
837
  - `x.owner_before(y)` defines a strict weak ordering as defined
 
847
  template<class T> void swap(weak_ptr<T>& a, weak_ptr<T>& b) noexcept;
848
  ```
849
 
850
  *Effects:* Equivalent to `a.swap(b)`.
851
 
852
+ #### Class template `owner_less` <a id="util.smartptr.ownerless">[[util.smartptr.ownerless]]</a>
853
 
854
  The class template `owner_less` allows ownership-based mixed comparisons
855
  of shared and weak pointers.
856
 
857
  ``` cpp
 
1078
  template<class T>
1079
  bool atomic_compare_exchange_weak(
1080
  shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w);
1081
  ```
1082
 
1083
+ *Requires:* `p` shall not be null and `v` shall not be null.
1084
 
1085
  *Returns:*
1086
  `atomic_compare_exchange_weak_explicit(p, v, w, memory_order_seq_cst, memory_order_seq_cst)`.
1087
 
1088
  *Throws:* Nothing.
 
1105
  bool atomic_compare_exchange_strong_explicit(
1106
  shared_ptr<T>* p, shared_ptr<T>* v, shared_ptr<T> w,
1107
  memory_order success, memory_order failure);
1108
  ```
1109
 
1110
+ *Requires:* `p` shall not be null and `v` shall not be null.
1111
 
1112
  *Requires:* `failure` shall not be `memory_order_release`,
1113
  `memory_order_acq_rel`, or stronger than `success`.
1114
 
1115
  *Effects:* If `*p` is equivalent to `*v`, assigns `w` to `*p` and has
 
1131
 
1132
  ``` cpp
1133
  template <class T, class D> struct hash<unique_ptr<T, D> >;
1134
  ```
1135
 
1136
+ The template specialization shall meet the requirements of class
1137
+ template `hash` ([[unord.hash]]). For an object `p` of type `UP`, where
1138
+ `UP` is `unique_ptr<T, D>`, `hash<UP>()(p)` shall evaluate to the same
1139
+ value as `hash<typename UP::pointer>()(p.get())`.
1140
+
1141
+ *Requires:* The specialization `hash<typename UP::pointer>` shall be
1142
+ well-formed and well-defined, and shall meet the requirements of class
1143
+ template `hash` ([[unord.hash]]).
1144
 
1145
  ``` cpp
1146
  template <class T> struct hash<shared_ptr<T> >;
1147
  ```
1148
 
1149
+ The template specialization shall meet the requirements of class
1150
+ template `hash` ([[unord.hash]]). For an object `p` of type
1151
  `shared_ptr<T>`, `hash<shared_ptr<T> >()(p)` shall evaluate to the same
1152
  value as `hash<T*>()(p.get())`.
1153