std::atomic 中的自定义类型

Custom type in std::atomic

我在 std::atomic 中放置了自定义 class Unit。 Class 使用默认构造函数看起来如下

namespace Base
{
    template <typename T, typename R, typename D>
    class Unit
    {
    public: 
        constexpr Unit() = default;
    private:
        T m_Value;
    };
}

它曾经工作得很好,直到我注意到我忘记在默认构造函数中将 class 的唯一成员初始化为零。因此我删除了 = default 并提供了构造函数的实现

template <typename T, typename R, typename D>
constexpr Unit<T, R, D>::Unit() :
    m_Value(T(0))
{   }

现在我遇到编译器错误:

Error C2280 'std::atomic<Base::Unit>::atomic(void) noexcept': attempting to reference a deleted function

我的直觉是,那是因为我现在提供了一个自定义构造函数,这导致默认复制构造函数不再被隐式定义。

所以,我也将其添加到 class 声明中

Unit(const Unit<T, R, D>& U) = default;

但是,我遇到了同样的错误。我不确定我会成为什么样的人。我不确定编译器指的是哪个已删除的函数。

如有任何帮助,我们将不胜感激

一种解决方法是删除构造函数并使用 default member initializers:

template<class T>
struct Unit {
    T value = 0;
};

int main() {
    std::atomic<Unit<int>> a;
    std::atomic<Unit<int>> b = {{1}};
}

这里的问题是你的类型的异常保证。 您的默认构造函数是 noexcept。当您添加自己的时,您不提供异常规范,因此它不是 noexcept。您需要做的是将其添加到您的默认构造函数中,因为 std::atomic 的默认构造函数被标记为 noexcept

namespace Base
{
    template <typename T, typename R, typename D>
    class Unit
    {
    public:
        constexpr Unit() noexcept;
    private:
        T m_Value;
    };

    template <typename T, typename R, typename D>
    constexpr Unit<T, R, D>::Unit() noexcept :
        m_Value(T(0))
    {   }
}

int main() 
{
    std::atomic<Base::Unit<int, int, int>> foo;
}