我可以使一些变量模板特定

Can I make some variables template specific?

本文关键字:变量 可以使 我可以      更新时间:2023-10-16

例如,这是我的线程屏障/section类型

template <bool switchable = false, bool counting = false>
struct SimpleBarrier {
private:
    std::mutex mtx;
    std::condition_variable cv;
    std::atomic<bool> enabled;
    std::atomic<int> inside;
public:
    SimpleBarrier() {
        if (switchable) enabled.store(true, std::memory_order_release);
        if (counting) inside.store(0, std::memory_order_release);
    }
    void enter() {
        if (switchable && !enabled.load(std::memory_order_acquire)) return;
        if (counting) inside.fetch_add(1, std::memory_order_acq_rel);
        std::unique_lock<std::mutex> lock(mtx);
        cv.wait(lock);
    }
    void leave() {
        if (counting) inside.fetch_sub(1, std::memory_order_acq_rel);
    }
    void release() {
        cv.notify_all();
    }
    void enable() {
        if (switchable) {
            enabled.store(true, std::memory_order_release);
        }
    }
    void disable() {
        if (switchable) {
            enabled.store(false, std::memory_order_release);
        }
    }
    bool is_empty() {
        if (counting) return inside.load(std::memory_order_acquire) == 0;
        return false;
    }
}; 

最初我只是想创建一堆类,如"SwitchableBarrier"answers"CountingSection"等,但后来我开始需要像"SwitchableCountingSection"这样的组合,并且可能会有更多的质量,所以为了避免创建一打类,我使用模板参数将它们合并为一个类,以打开/关闭某些质量。

使用模板参数作为条件允许编译器优化掉不使用的特性,这样就不会有不使用的额外开销。问题是,是否有可能使它优化掉类变量?

以变量"inside"为例,如果count == false,那么它是完全无用的,不需要在那里。我可以有模板参数特定的类变量?

任何成员,即使未使用,也有不同的地址。而且,编译器不会删除它。然而,有一个简单的技巧:空基地不需要获得自己的地址。如果这与专门化相结合,您就可以摆脱任何数据。例如:

template <bool, typename T>
class conditional_count {
    std::atomic<T> value;
public:
    T    load_count() { return value.load(std::memory_order_aquire); }
    void store_count(T v) { value.store(v, std::memory_order_release); }
    // ...
};
template <typename T>
struct conditional_count<false, T> {
    int  load_count() { return 0; }
    void store_count(T) {}
    // ...
};
template <bool switchable = false, bool counting = false>
struct SimpleBarrier
     : private conditional_count<counting> {
    // use this->load_count(), this->store_count(), etc.
 };

创建更通用的conditional_atomic<...>是可能的,但它需要使用额外的标签类型来识别正在使用的是哪一个,并且使用起来有点烦人。但是,总体方法是将逻辑放入具有访问变量的合适函数的基中,并提供什么都不做的专门化。