这可能是一个简单的问题,我根本不掌握 C++11 模板。
我有一个通用向量类,但不是std::vector<T>
出于性能原因(非常具体的代码)。
我观察到检查是否T
无论是否是 POD,如果是,则执行特殊计算,比不是时要高效得多:
void vec<T>::clear() {
if (!std::is_pod<T>::value) {
for (int i = 0; i < size; i++) {
data[i].~T();
}
}
size = 0;
}
在这里,我不调用析构函数T
对于每个项目(size
可能非常巨大)并且性能确实得到了提升。但测试if (!std::is_pod<T>::value)
一旦模板被编译,就没用了:而不是被编译为:
void vec<int>::clear() {
if (false) {
for (int i = 0; i < size; i++) {
data[i].~int();
}
}
size = 0;
}
我希望将其编译为:
void vec<int>::clear() {
size = 0;
}
编译器是否“聪明”到足以跳过if (false)
块或if (true)
测试?我是否必须以不同的方式编写该代码?
编译器是否“聪明”到足以跳过 if (false) 块或 if (true) 测试?
当然是。消除死代码 http://en.wikipedia.org/wiki/Dead_code_elimination是常规执行的简单优化。它的存在对于使许多调试库高效工作(= 在发布模式下没有运行时开销)也至关重要。
但我可能仍然会重写这个来实现它读者可见这是编译时的区别,通过重载基于的函数is_pod
:
void vec<T>::do_clear(std::true_type) { }
void vec<T>::do_clear(std::false_type) {
for (int i = 0; i < size; i++) {
data[i].~T();
}
}
void vec<T>::clear() {
do_clear(std::is_trivially_destructible<T>());
size = 0;
}
在上面的代码中我使用的是is_trivially_destructible http://en.cppreference.com/w/cpp/types/is_destructible代替is_pod
正如 Nicol 在评论中所建议的那样,使代码更加不言自明。该技术通常用于标准库实现和其他库。它被称为标签调度 http://www.boost.org/community/generic_programming.html#tag_dispatching.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)