例如,这是我的线程障碍/部分类型的东西
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”和“CountingSection”等类,但后来我开始需要像“SwitchableCountingSection”这样的组合,并且可能会有更多的特性以避免打十几个课程,我使用模板参数将它们滚动到一个类中,以打开/关闭某些特性。
使用模板参数作为条件允许编译器优化掉未使用的质量,因此没有未使用的质量的额外开销。问题是 - 是否有可能使它优化掉类变量?
以变量“inside”为例,如果计数== false则它完全没用,不需要在那里。我可以使用模板参数特定的类变量吗?
答案 0 :(得分:0)
任何成员即使在未使用时也会有不同的地址。此外,编译器不会删除它。但是,有一个简单的伎俩:空基不需要获取自己的地址。如果将其与专业化结合使用,则可以删除任何数据。例如:
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<...>
,但是需要采用额外的标签类型来识别正在使用哪一个,并且使用起来会变得更加烦人。但是,整体方法是将逻辑放入具有适当函数的基础中以访问变量并提供无需任何操作的特化。