T
のような型が存在するstd::is_trivially_destructable<T>::value == true
と仮定し、さらにそれT
が何らかのベクトル クラスの値の型であると仮定します。ベクターのデストラクタが呼び出されるか、ベクターが別のベクターに割り当てられると、現在のストレージを破棄して割り当てを解除する必要があります。自明に破壊可能であるため、のデストラクタT
を呼び出す必要がありT
ますか?
ご協力いただきありがとうございます!
T
のような型が存在するstd::is_trivially_destructable<T>::value == true
と仮定し、さらにそれT
が何らかのベクトル クラスの値の型であると仮定します。ベクターのデストラクタが呼び出されるか、ベクターが別のベクターに割り当てられると、現在のストレージを破棄して割り当てを解除する必要があります。自明に破壊可能であるため、のデストラクタT
を呼び出す必要がありT
ますか?
ご協力いただきありがとうございます!
C++ 標準 (セクション 3.8) によると、ストレージの割り当てを解除または再利用することで、オブジェクトの有効期間を終了できます。何もしないデストラクタを呼び出す必要はありません。一方、空のデストラクタをコンパイラに最適化させると、通常はコードがよりクリーンでシンプルになります。コレクションを繰り返し処理するなど、実質的な追加作業を節約できる場合にのみ、単純なデストラクタを特別なケースにする必要があります。
libstdc++ (gcc がデフォルトで使用する標準ライブラリ) は、この最適化を正確に適用します。
117 /**
118 * Destroy a range of objects. If the value_type of the object has
119 * a trivial destructor, the compiler should optimize all of this
120 * away, otherwise the objects' destructors must be invoked.
121 */
122 template<typename _ForwardIterator>
123 inline void
124 _Destroy(_ForwardIterator __first, _ForwardIterator __last)
125 {
126 typedef typename iterator_traits<_ForwardIterator>::value_type
127 _Value_type;
128 std::_Destroy_aux<__has_trivial_destructor(_Value_type)>::
129 __destroy(__first, __last);
130 }
そしてstd::_Destroy_aux
forの特殊化__has_trivial_destructor(_Value_type) == true
:
109 template<>
110 struct _Destroy_aux<true>
111 {
112 template<typename _ForwardIterator>
113 static void
114 __destroy(_ForwardIterator, _ForwardIterator) { }
115 };
よく書かれた他のほとんどの標準ライブラリの実装が同じことをすると思います。
いいえ、デストラクタを明示的に呼び出す必要はありません。vector
これはのデストラクタによって行われます。