Пользовательский тип в std :: atomic - PullRequest
0 голосов
/ 05 октября 2018

Я поместил пользовательский класс Unit в std::atomic.Класс выглядел следующим образом с конструктором по умолчанию

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

Раньше он работал нормально, пока я не заметил, что забыл инициализировать единственный член моего класса нулем в конструкторе по умолчанию.Поэтому я удалил = 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

Я догадывался, чтоэто связано с тем, что теперь я предоставляю собственный конструктор, который не дает неявно определенному конструктору копирования по умолчанию.

Итак, я добавил это также в объявление класса

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

Однако я получаю ту же ошибку.Я не уверен, что я мог бы быть.Я не уверен, на какую удаленную функцию ссылается компилятор.

Любая помощь будет признательна

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

Проблема здесь - гарантия исключения вашего типа. На этот пост / ссылку ваш конструктор по умолчанию - 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;
}
0 голосов
/ 05 октября 2018

Один из обходных путей - удалить конструктор и использовать инициализаторы членов по умолчанию :

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

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