Suppose there exists a type T
such that std::is_trivially_destructable<T>::value == true
, and suppose further that T
is the value type of some vector class. When the vector's destructor is called, or the vector is assigned to another vector, it must destroy and deallocate its current storage. As T
is trivially destructable, is it necessary that I call T
's destructor?
Thanks for your help!
According to the C++ Standard (section 3.8), you can end an object's lifetime by deallocating or reusing its storage. There's no need to call a destructor that does nothing. On the other hand, letting the compiler optimize away an empty destructor usually results in cleaner and simpler code. Only if you can save substantial additional work, such as iterating through the collection, would you want to special-case trivial destructors.
libstdc++ (the standard library the gcc uses by default) applies precisely this optimisation:
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 }
And the specialisation of 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 };
I would expect that most other well-written standard library implementations do the same.
No, you don't need to call the destructors explicitly. This will be done by the vector
's destructor.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With