Search code examples
c++variantstandard-layouttrivially-copyableanonymous-union

C++ struct with anonymous union


---- updated -------------------------------------------

At first, I think that the problem I faced is trivially_copyable. In fact, even I give up making it trivially_copyable, it still can NOT be compiled.

Now, I'm only trying to get it pass compilation.

---- original question ---------------------------------

I have a struct that will be sent/received between processes through some type of message queue, so I want to make it fixed length, and standard_layout and trivially_copyable.

There are multiple types of my message(e.g. timer-msg, control-msg, order-msg and so on), then I'm trying to use a union to carry different types of messages.

The reason I don't want to use std::variant, is that I want to exactly control the length and the layout of my message struct.

Furthermore, I don't want to code too long when I refer its members. For example: msg.as_time is little more readable than msg.union_body.as_time. So I plan to use an anonymous union to carry the message body.

I'm expecting this(but it was rejected by gcc):

#include <chrono>

using TimeStamp_t = std::chrono::system_clock::time_point;

enum MsgType_e { Timer, Count, };

struct Message_t {
    union {
        TimeStamp_t as_time;
        int64_t     as_int;
    };

    MsgType_e  type;
};

static_assert( std::is_standard_layout_v<Message_t> );
static_assert( std::is_trivially_copyable_v<Message_t> );

int main() {
    Message_t msg;
    std::cout << msg.as_time.time_since_epoch().count();
}

Eventhough MsgType_e and TimeStamp_t are both trivially_copyable, Message_t is NOT, as long as I put TimeStamp_t into a anonymous union.

error: use of deleted function 'Message_t::Message_t()'

note: 'Message_t::Message_t()' is implicitly deleted because the default definition would be ill-formed:

union member 'Message_t::::as_time' with non-trivial 'constexpr std::chrono::time_point<_Clock, _Dur>::time_point() [with _Clock = std::chrono::_V2::system_clock; _Dur = std::chrono::duration<long int, std::ratio<1, 1000000000> >]'

How to make this struct trivially_copyable?


Solution

  • How to make this struct trivially_copyable?

    I would just follow the directions in the error message:

    error: use of deleted function 'Message_t::Message_t()'

    Just add one:

    Message_t() : as_time{}, type{} {}
    

    Works here.