Search code examples
c++constructoratomiccopy-constructorstdatomic

Custom type in std::atomic


I've put a custom class Unit in an std::atomic. Class looked as follows with a default constructor

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

It used to work fine until I noticed I forgot to initialize the only member of my class to zero in the default constructor. Therefore I removed the = default and provided an implementation of the constructor

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

Now I am getting a compiler error:

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

My hunch was that that's because of the fact that I now provide a custom constructor, which causes the default copy constructor to no longer be implicit defined.

So, I added this as well to the class declaration

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

However, I'm getting the same error. I'm not sure what I could be. I'm not sure which deleted function the compiler is referring to.

Any help would be appreciated


Solution

  • The issue here is the exception guarantee of your type. Per this post/reference your default constructor is noexcept. When you add your own, you do not provide an exception specification so it is not noexcept. What you need to do is add that to your default constructor since std::atomic's default constructor is marked as 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;
    }