SFINAE to disable POD structure with pointers in C++

Viewed 78

I'm looking for solution to disable using as a template parameter structures that are POD (or say copyable) but has pointers. I'm going to send them over network. E.g.

// good
struct S1 {
    int x;
    S1() : x( 42 ) {} // I know that it's not a POD, but I know, that I can send S1 over network
};
// bad
struct S2 {
    int *x;
};

template<typename POD>
class ToNetwork {
    //static_assert( std::is_trivially_copyable< POD >::value, "Type must be POD" );
    static_assert( std::is_standard_layout< POD >::value, "Type must be POD" );
    POD m_payload;
};
ToNetwork< S1 > s1;
ToNetwork< S2 > s2; // should fail, but not((

Either is_trivially_copyable or is_standard_layout say that both structures are good.

1 Answers

This is partly a frame challenge answer: to correctly serialize something, it is anyway not sufficient to have only non-pointer trivial members.

Even if you currently only talk to peers on the same platform, depending on this is brittle (ie, you'll have to document your endianness and data sizes when someone wants to connect with an ARM/RISC/M1/other device).

Further, the padding and alignment requirements of in-memory and on-wire types rarely agree. You tend to end up either (de)serializing member-by-member, or writing a packed/misaligned overlay struct which is less efficient for in-memory use (and is also non-portable).

This means in practice you're going to declare dedicated types for sending over the network - either ones with their own (de)serialize methods, or ones with some metadata, or ones with __attribute__((packed)), or whatever. Since they're dedicated to this, it's trivial to give them a member or nested type for your SFINAE to detect directly.

Related