C++ 如何在编译时检测平凡的析构函数?

C++ 如何在编译时检测平凡的析构函数?,c++,sfinae,C++,Sfinae,我有一个模板化的容器类,看起来像这样: template <class ItemType> class MyContainer { public: [... various methods omitted for brevity...] void Clear() { ItemType defaultItem; for (int i=0; i<_numValidItems; i++) _itemArray[i] = defaultIte

我有一个模板化的容器类,看起来像这样:

template <class ItemType> class MyContainer
{
public:
   [... various methods omitted for brevity...]

   void Clear()
   {
      ItemType defaultItem;
      for (int i=0; i<_numValidItems; i++) _itemArray[i] = defaultItem;
      _numValidItems = 0;
   }

   void FastClear()
   {
      _numValidItems = 0;
   }

private:
   int _numValidItems;
   ItemType * _itemArray;
};
模板类MyContainer
{
公众:
[…为简洁起见省略了各种方法…]
无效清除()
{
ItemType defaultItem;

对于(inti=0;i调用析构函数的正确方法是

void Clear()
{
    for (int i = 0; i < _numValidItems; ++ i)
    {
        _itemArray[i].~ItemType();
    }
    _numValidItems = 0;
}
void Clear()
{
对于(int i=0;i<\u numValidItems;++i)
{
_itemArray[i]。~ItemType();
}
_numValidItems=0;
}
GCC4.6(在-O2或更高版本)上的优化器将在析构函数不重要时消除循环(不确定是否为4.2,您可以自己检查)。例如,对于ItemType等于
std::pair
,您的Clear()版本将生成

0000000000000000:
0:8b 0f mov ecx,DWORD PTR[rdi]
2:85 c9测试ecx,ecx
4:7e 34 jle 3a
6:83 e9 01子ecx,0x1
9:48 8b 57 08 mov rdx,QWORD PTR[rdi+0x8]
d:31 c0 xor eax,eax
f:48 83 c1 01添加rcx,0x1
13:48 c1 e1 04 shl rcx,0x4
17:66 0f 1f 84 00 nop字PTR[rax+rax*1+0x0]
1e:00
20:48 c7 04 02 00 mov QWORD PTR[rdx+rax*1],0x0
27:   00 
28:48 c7 44 02 08 00 mov QWORD PTR[rdx+rax*1+0x8],0x0
2f:00
31:48 83 c0 10添加rax,0x10
35:48 39 c8 cmp rax,rcx
38:75 e6 jne 20
3a:c7 07 00 mov德沃德PTR[rdi],0x0
40:c3 ret
当我的版本产生

0000000000000000 <_ZN11MyContainerISt4pairIddEE5ClearEv>:
   0:   c7 07 00 00 00 00       mov    DWORD PTR [rdi],0x0
   6:   c3                      ret    
0000000000000000:
0:c7 07 00 mov DWORD PTR[rdi],0x0
6:c3 ret

既然GCC4.2已经绑定了TR1,我不知道为什么你不能使用
std::TR1::has_trial_destructor

我会选择它。我认为它很好地回答了你的问题。如果你不想要包含,你可以自己实现它,使用Boost作为灵感。它毕竟使用了SFINAE

0000000000000000 <_ZN11MyContainerISt4pairIddEE5ClearEv>:
   0:   c7 07 00 00 00 00       mov    DWORD PTR [rdi],0x0
   6:   c3                      ret