繁体   English   中英

使用 C++11 模板生成一个算法的多个版本

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM