libstdC ++ (the standard library used by gcc by default) uses this particular optimization :
117
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 specialization std::_Destroy_auxfor __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 most other well-written standard library implementations to do the same.