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?
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.