Буст-блокировка свободной очереди утверждает для тривиального назначения и деструктора - PullRequest
0 голосов
/ 10 июня 2019

При попытке вставить «Событие» в очередь без принудительной блокировки я получаю: ошибка: статическое утверждение не удалось: (boost :: has_trivial_destructor :: value) и статическое утверждение не удалось: (boost :: has_trivial_assign :: value). Я знаю, что требование к контейнеру: T должен иметь конструктор копирования T должен иметь тривиальный оператор присваивания Т должен иметь тривиальный деструктор Я не уверен, почему мой класс мероприятий не соответствует этим требованиям.

Я прочитал этот вопрос / ответ: / boost / lockfree / queue.hpp: ошибка: статическое утверждение не удалось: (boost :: has_trivial_destructor :: value) . Я не понимаю, почему мой класс не соответствует требованиям.

struct Event
{
    typedef uint8_t Event_Type;

    //event bitmask..
    enum : uint8_t
    {
        SS      = 1,
        TS      = 2
    };

    static constexpr uint8_t BOTH = SS | TS;

    Event():      _time {}
                  ,_data1 {}
                  ,_eventType {}
                  ,_data2 {}
    {}

    Event(const Event& event_)
    {
        _id                  = event_._id;
        _time                = event_._time;
        _data1                = event_.data1;
        _eventType           = event_._eventType;
        _data2                = event_.data2;
    }

    template<Event_Type type, typename... Args >
    void update(Args...args)
    {
        _eventType |= type;
        apply(std::forward<Args>(args)...);
    }

    void apply(int32_t d)
    {
        data1 = d;
    }

    void apply(bool b)
    {
        data2= b;
    }

    template<typename Event, typename... Args>
    void apply(Event event, Args... args)
    {
        apply(event);
        apply(args...);
    }

    std::string                _id;
    int64_t                    _time;
    int32_t                    _data1;
    Event_Type                 _eventType;
    bool                       _data2;
};

boost::lockfree::queue<Event, boost::lockfree::fixed_sized<false>> q;
Event e;
e._id="test";    
q.push(event);

/ boost / 1.57.0 / include / boost / static_assert.hpp: 78: 41: ошибка: статическое утверждение не удалось: (boost :: has_trivial_destructor :: value) # define BOOST_STATIC_ASSERT (...) static_assert ( VA_ARGS , # VA_ARGS )

boost / 1.57.0 / include / boost / static_assert.hpp: 78: 41: ошибка: статическое утверждение не удалось: (boost :: has_trivial_assign :: value) # define BOOST_STATIC_ASSERT (...) static_assert ( VA_ARGS , # VA_ARGS )

Ответы [ 3 ]

3 голосов
/ 10 июня 2019

Ваш класс Event имеет член типа std::string, который имеет нетривиальный оператор присваивания и нетривиальный деструктор.Они мешают автоматически сгенерированному оператору присваивания и самому деструктору Event быть тривиальными.(Помните, что «тривиальный» означает не просто «дефолт». Он также означает, что поведение по умолчанию не должно делать ничего интересного. Тривиальное назначение - просто копирование битов; тривиальный деструктор - неоперативный.)

1 голос
/ 11 июня 2019

В дополнение к двум другим ответам, отметив, что элемент данных std::string не позволяет конструктору быть тривиальным, сам конструктор Event() должен быть тривиальным. Это означает, что он должен быть сгенерирован компилятором и не реализован пользователем. Этого можно достичь, либо полностью удалив конструктор, либо пометив его как явное значение по умолчанию (Event() = default;). То же самое верно для конструктора копирования и оператора присваивания.

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

1 голос
/ 10 июня 2019

std::string не имеет оператора тривиального копирования или тривиального деструктора. Поскольку это не так, и он является членом вашего класса, это означает, что ваш класс не так хорошо. Вы должны удалить строковый член, если хотите, чтобы он был тривиальным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...