C++ 琐碎破坏性与调用析构函数的必要性

C++ 琐碎破坏性与调用析构函数的必要性,c++,memory,c++11,destructor,typetraits,C++,Memory,C++11,Destructor,Typetraits,假设存在一个类型T,使得std::is_minally_destructable::value==true,并且进一步假设T是某个向量类的值类型。当调用向量的析构函数或将向量分配给另一个向量时,它必须销毁并释放其当前存储。由于T是可分解的,我是否需要调用T的析构函数 谢谢你的帮助 >根据C++标准(第3.8节),可以通过释放或重用存储来结束对象的生命周期。不需要调用不执行任何操作的析构函数。另一方面,让编译器优化掉一个空的析构函数通常会产生更干净、更简单的代码。只有在可以节省大量额外工作(如遍历

假设存在一个类型
T
,使得
std::is_minally_destructable::value==true
,并且进一步假设
T
是某个向量类的值类型。当调用向量的析构函数或将向量分配给另一个向量时,它必须销毁并释放其当前存储。由于
T
是可分解的,我是否需要调用
T
的析构函数


谢谢你的帮助

>根据C++标准(第3.8节),可以通过释放或重用存储来结束对象的生命周期。不需要调用不执行任何操作的析构函数。另一方面,让编译器优化掉一个空的析构函数通常会产生更干净、更简单的代码。只有在可以节省大量额外工作(如遍历集合)的情况下,才需要使用特殊情况的平凡析构函数。

否,不需要显式调用析构函数。这将由
向量的析构函数完成。

libstdc++(gcc默认使用的标准库)适用于:


我希望大多数其他编写良好的标准库实现也能做到这一点。

你不必调用任何析构函数,向量会为你做这件事。在担心编译器优化空循环之前,请看看这个例子,其中递归函数的结果是在编译时计算的。避免向量析构函数中的迭代开销是优化这种情况的一个很好的理由。是的,这就是我在提问时想到的用例。如果编译器真的很好,它可能能够优化<代码>(Ly.O.F.{)-Ly;Ly-> > ValueEype();} > <代码> Ly= Fy,但我更依赖于Type Myth.@空格指针:使优化是C++标准语言要求的全部(1.10p24)。每个线程必须执行易失性或同步操作、I/O或终止。
while
循环不允许是无限的,因为当有一个微不足道的析构函数时,它没有副作用,所以正式允许进行优化。即使编译器无法证明迭代器减量曾经达到@void指针,也要检查标准库;
std::vector
很有可能精确地实现您建议的优化。确切的规则是3.8.4:您不必调用任何析构函数。然而,如果您选择不调用它,任何依赖于破坏的副作用的程序都会得到未定义的行为。这是可以具体说明的:因为琐碎的析构函数没有副作用,所以您可以随时决定不调用它们,而不会产生任何影响。感谢实际的源代码清单!很高兴知道我的实现利用了这种优化。实际上我想知道,因为我在写一个不同的数据结构。
  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     }
  109   template<>
  110     struct _Destroy_aux<true>
  111     {
  112       template<typename _ForwardIterator>
  113         static void
  114         __destroy(_ForwardIterator, _ForwardIterator) { }
  115     };