std::tuple and standard layout

前端 未结 4 2364
感情败类
感情败类 2021-02-19 05:10

If all of the members of std::tuple are of standard layout types, is that std::tuple itself standard layout? The presence of a user-defined copy-constr

4条回答
  •  醉梦人生
    2021-02-19 05:29

    One reason std::tuple cannot be of standard layout, as any classes with members and base classes with members, is that the standard allows for space optimization when deriving even non-empty base classes. For example:

    #include 
    #include 
    
    class X
    {
        uint64_t a;
        uint32_t b;
    };
    
    class Y
    {
        uint16_t c;
    };
    
    class XY : public X, public Y
    {
        uint16_t d;
    };
    
    int main() {
        printf("sizeof(X) is %zu\n", sizeof(X));
        printf("sizeof(Y) is %zu\n", sizeof(Y));
        printf("sizeof(XY) is %zu\n", sizeof(XY));
    }
    

    Outputs:

    sizeof(X) is 16
    sizeof(Y) is 2
    sizeof(XY) is 16
    

    The above shows that the standard allows for class trailing padding to be used for the derived class members. Class XY has two extra uint16_t members, yet its size equals to the size of base class X.

    In other words, class XY layout is the same as that of another class that has no base classes and all the members of XY ordered by address, e.g. struct XY2 { uint64_t a; uint32_t b; uint16_t c; uint16_t d; };.

    What makes it non-standard layout is that the size of a derived class is not a function of sizes of base classes and derived class members.

    Note that the size of a struct/class is a multiple of the alignment of one of its members with the largest alignment requirement. So that an array of objects is suitably aligned for such a member. For built-in types normally sizeof(T) == alignof(T). Hence sizeof(X) is a multiple of sizeof(uint64_t).

    I am not sure whether the standard requires special treatment for struct, but with g++-5.1.1 if class is replaced with struct the above code yields different output:

    sizeof(X) is 16
    sizeof(Y) is 2
    sizeof(XY) is 24
    

    In other words, the trailing padding space optimization is not used when struct is involved (did not test for exact conditions).

提交回复
热议问题