gpt4 book ai didi

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

转载 作者:搜寻专家 更新时间:2023-10-31 00:43:53 26 4
gpt4 key购买 nike

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

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;
};

如您所见,Clear() 方法将容器中的每个项目重置为其默认状态,这对于类型来说是必需的,例如各个项目动态分配了我希望 Clear() 调用释放的内部资源。

还有 FastClear(),顾名思义速度更快(O(1) 而不是 O(N)),因为它只是将 _numValidItems 设置为零,实际上并不触及大批。这对于 POD 样式的 ItemTypes 非常有用,但对于例如文件句柄类型。

我的问题是,有没有一种方法可以使用 SFINAE 或类似工具让编译器在编译时决定将 Clear() 设为 FastClear() 的同义词是安全的,即当 ItemType 具有平凡的析构函数时?这样调用代码就不必记住调用 FastClear() 而不是 Clear 来获得加速,它会自动运行。

另外,只是为了让事情变得更困难......我希望能够在不添加对 Boost/TR1/C++11 的依赖的情况下做到这一点。 (所以调用 is_pod() 或 has_trivial_destructor() 对我来说不是好的选择)

最佳答案

调用析构函数的正确方法是

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

gcc 4.6 上的优化器(在-O2 或更高版本)会在析构函数很简单时消除循环(4.2 不确定,你自己检查)。例如,ItemType 等于 std::pair<double, double> ,您的 Clear() 版本产生

0000000000000000 <_ZN11MyContainerISt4pairIddEE8BadClearEv>:
0: 8b 0f mov ecx,DWORD PTR [rdi]
2: 85 c9 test ecx,ecx
4: 7e 34 jle 3a <_ZN11MyContainerISt4pairIddEE8BadClearEv+0x3a>
6: 83 e9 01 sub ecx,0x1
9: 48 8b 57 08 mov rdx,QWORD PTR [rdi+0x8]
d: 31 c0 xor eax,eax
f: 48 83 c1 01 add rcx,0x1
13: 48 c1 e1 04 shl rcx,0x4
17: 66 0f 1f 84 00 00 00 nop WORD PTR [rax+rax*1+0x0]
1e: 00 00
20: 48 c7 04 02 00 00 00 mov QWORD PTR [rdx+rax*1],0x0
27: 00
28: 48 c7 44 02 08 00 00 mov QWORD PTR [rdx+rax*1+0x8],0x0
2f: 00 00
31: 48 83 c0 10 add rax,0x10
35: 48 39 c8 cmp rax,rcx
38: 75 e6 jne 20 <_ZN11MyContainerISt4pairIddEE8BadClearEv+0x20>
3a: c7 07 00 00 00 00 mov DWORD PTR [rdi],0x0
40: c3 ret

当我的版本产生

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

而且由于 gcc 4.2 已经与 TR1 捆绑在一起,我不知道为什么你不能使用 std::tr1::has_trivial_destructor .

关于c++ - 如何在编译时检测平凡的析构函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9858635/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com