派生std :: atomic <T>类的template-specializaiton

时间:2019-11-07 09:06:30

标签: c++

我需要一个具有复制构造函数的原子,因为我有一个包含原子的对象向量。当然,不需要复制原子的同步状态,但是需要复制内容。我实际上并不需要复制对象,但是我有一个vector,它的大小从零调整为N,并且::resize自然地依赖于复制构造函数,因为它不仅是为了将vom调整为零。 emplace_back也无济于事,因为它还会有条件地调整向量的大小,从而调用复制构造函数。

[编辑]:

整数类型的“专业化”将是这样:

#include <atomic>
#include <type_traits>

template <typename T, typename T2 = typename std::enable_if<std::is_integral<T>::value, T>::type>
struct xatomic : public std::atomic<T>
{
    xatomic() = default;
    xatomic( xatomic const &xa );

    using std::atomic<T>::operator =;
    using std::atomic<T>::is_lock_free;
    using std::atomic<T>::store;
    using std::atomic<T>::load;
    using std::atomic<T>::operator T;
    using std::atomic<T>::exchange;
    using std::atomic<T>::compare_exchange_weak;
    using std::atomic<T>::compare_exchange_strong;
    using std::atomic<T>::fetch_add;
    using std::atomic<T>::fetch_sub;
    using std::atomic<T>::operator ++;
    using std::atomic<T>::operator --;
    using std::atomic<T>::operator +=;
    using std::atomic<T>::operator -=;
    using std::atomic<T>::fetch_and;
    using std::atomic<T>::fetch_or;
    using std::atomic<T>::fetch_xor;
    using std::atomic<T>::operator &=;
    using std::atomic<T>::operator |=;
    using std::atomic<T>::operator ^=;
};

 template<typename T, typename T2>
inline
xatomic<T, T2>::xatomic( xatomic const &xa )
{
    *this = (T)xa;
}

但是如何获得非整数的“专业化”?

1 个答案:

答案 0 :(得分:0)

不是将复制语义反向移植到atomic类型(即使可能,这也不容易),一种替代解决方案是避免复制它们。

从注释看来,您似乎仅在启动/初始化时需要它,并且因为vector::resize()需要它。因此,我们可以通过各种方式避免该问题。
例如:

  1. 计算您需要多少atomic,然后一次创建它们。

    int n = 100;
    std::vector<std::atomic<int>> vec(n); // does not involve copying
    

    之所以可行,是因为vector<T>(size_t n)仅要求TDefaultConstructible

  2. 如果atomic是较大结构的一部分,请创建一个自定义副本构造函数,该构造函数将正确初始化所有atomic成员而不是复制它们。

  3. 使用在调整大小时不会移动元素的数据结构。例如,std::liststd::deque


关于vector<atomic<int>>的附加说明:将无关线程的数据存储得太近会导致false sharing。因此,从性能的角度来看,像vector<atomic<int>>这样的数据结构可能不是一个好主意。