[英]using C++11 templates to generate multiple versions of an algorithm
假设我正在制作某种类型的通用集合,并且有 4-5 点用户可能想要选择实现 A 或 B。例如:
我可以针对每种功能组合进行 16 或 32 个实现,但显然这不容易编写或维护。
我可以将布尔标志传递给构造函数,类可以在执行某些操作之前进行检查。 但是,编译器不“知道”这些参数是什么,因此必须每次都检查它们,并且仅检查足够的布尔标志本身就会带来性能损失。
所以我想知道是否可以以某种方式使用模板参数,以便在编译时编译器看到if (false)
或if (true)
,因此可以完全优化条件测试,如果为 false,则优化条件代码。 然而,我只找到了模板作为类型的例子,而不是编译时常量。
主要目标是完全消除对锁定互斥锁、递增和递减计数器等的调用,但此外,如果有某种方法可以从对象结构中实际删除互斥锁或计数器,那才是真正的最佳选择。
17 之前的条件计算主要是关于模板特化。 要么专门化功能本身
template<> void f<int>(int) {
std::cout << "Locking an int...\n";
std::cout << "Unlocking an int...\n";
}
template<> void f<std::mutex>(std::mutex &m) {
m.lock();
m.unlock();
}
但这实际上创建了一个相当分支的代码(在你的情况下我怀疑),所以更合理的选择是将所有依赖的、特定于类型的部分提取到静态接口中,并为特定的具体类型定义它的静态实现:
template<class T> struct lock_traits; // interface
template<> struct lock_traits<int> {
void lock(int &) { std::cout << "Locking an int...\n"; }
void unlock(int &) { std::cout << "Unlocking an int...\n"; }
};
template<> struct lock_traits<std::mutex> {
void lock(std::mutex &m) { m.lock(); }
void unlock(std::mutex &m) { m.unlock(); }
};
template<class T> void f(T &t) {
lock_traits<T>::lock(t);
lock_traits<T>::unlock(t);
}
在 C++17 中, if constrexpr
最终引入了if constrexpr
,现在并不是所有的分支都必须在所有情况下编译。
template<class T> void f(T &t) {
if constexpr<std::is_same_v<T, std::mutex>> {
t.lock();
}
else if constexpr<std::is_same_v<T, int>> {
std::cout << "Locking an int...\n";
}
if constexpr<std::is_same_v<T, std::mutex>> {
t.unlock();
}
// forgot to unlock an int here :(
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.