【问题标题】:using C++11 templates to generate multiple versions of an algorithm使用 C++11 模板生成算法的多个版本
【发布时间】:2020-08-30 06:45:09
【问题描述】:

假设我正在制作某种通用集合,用户可能希望在 4-5 个点上选择实现 A 或 B。例如:

  • 同质或异质
  • 我们是否维护包含对象的计数,这比较慢
  • 我们是否让它是线程安全的

我可以做 16 或 32 个实现,每个功能组合,但显然这并不容易编写或维护。

我可以将布尔标志传递给构造函数,该类可以在执行某些操作之前进行检查。但是,编译器并不“知道”这些参数是什么,因此每次都必须检查它们,并且仅检查足够的布尔标志本身就会造成性能损失。

所以我想知道是否可以以某种方式使用模板参数,以便在编译时编译器看到if (false)if (true),因此可以完全优化条件测试,如果为假,则条件代码。但是,我只发现模板作为类型的示例,而不是编译时常量。

主要目标是彻底消除对锁定互斥锁、递增和递减计数器等的调用,但此外,如果有某种方法可以从对象结构中实际移除互斥锁或计数器,那将是真正的最佳选择.

【问题讨论】:

  • if constexpr 是在 C++17 中引入的。在此之前,模板专业化是唯一的选择。
  • @bipll 模板专业化?这适用于这里吗?

标签: c++11 templates


【解决方案1】:

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 终于被引入了,现在并不是所有的分支都必须在所有情况下都编译。

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 :(
}

【讨论】:

  • 好的,但是如果我很高兴看到代码读取if (true) 并且只是相信编译器优化会删除它呢?您展示的代码非常有趣,但在未优化的构建中删除代码不是优先事项...
  • 好吧,如果你确定它可以编译的话。你不能真正锁定一个 int,所以当 Tint 时,if(std::is_same_v&lt;T, std::mutex&gt;) t.lock(); 不会编译,但 if constexpr(std::is_same_v&lt;T, std::mutex&gt;) t.lock(); 会。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-23
  • 2018-11-09
  • 2011-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多