1
votes

When trying to insert an "Event" into boost lock free queue, I receive: error: static assertion failed: (boost::has_trivial_destructor::value) and static assertion failed: (boost::has_trivial_assign::value). I know the requirement of the container is : T must have a copy constructor T must have a trivial assignment operator T must have a trivial destructor I am not sure why my event class does not meet these requirements.

I've read this question/answer : /boost/lockfree/queue.hpp: error: static assertion failed: (boost::has_trivial_destructor<T>::value). I don't see why my class doesn't satisfy the requirements.

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: error: static assertion failed: (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: error: static assertion failed: (boost::has_trivial_assign::value) # define BOOST_STATIC_ASSERT( ... ) static_assert(VA_ARGS, #VA_ARGS)

3

3 Answers

3
votes

Your Event class has a member of type std::string, which has a non-trivial assignment operator and a non-trivial destructor. Those stop the auto-generated assignment operator and destructor of Event itself from being trivial. (Remember, "trivial" doesn't just mean "defaulted". It also means that the default behavior doesn't have to do anything interesting. A trivial assignment is just copying bits; a trivial destructor is a no-op.)

2
votes

In addition to the other two answers noting that the std::string data member prevents the constructor from being trivial, the Event() constructor itself must be trivial. This means it must be generated by the compiler and not implemented by user. It can be achieved either by completely removing the constructor or by marking it as explicitly defaulted (Event() = default;). The same is true for the copy constructor and assignment operator.

In general, the requirements for a trivial default constructor are listed here.

1
votes

std::string does not have a trivial copy assignment operator or a trivial destructor. Because it does not, and it is a member of your class, that means your class does not as well. You have to remove the string member if you want it to be trivial.