Search code examples
c++aggregatec++20

Is there a way to create a non-copyable aggregate struct in c++20?


In C++20, aggregates can have no user-declared or inherited constructors (so you can't declare them deleted). So is there a way have a struct still be an aggregate, but non-copyable?


Solution

  • Per the rules on aggregates you can't have the deleted constructor on the aggregate itself but on a base class e.g.:

    struct bar{
        // having the defaulted constructor is required for C++20 aggregate initialization to work
        bar() = default;
        // prevents copy and deletes other constructors
        bar(const bar&) = delete;
    };
    
    struct foo : bar{
        int a;
    };
    

    You can then initialize it using aggregate syntax:

    foo b {{}, 1};
    
    // or
    
    foo c { .a = 1};
    

    This will work (mostly) fine: working example

    However there are clear tradeoffs as adding inheritance will break some functionality. For example: https://godbolt.org/z/P8Ea61oh3

    std::optional<foo> e(std::in_place, {}, 1);
    

    Will break.