2

Aggregate initialization is a special form of list initialization which can be used for aggregate types.

An aggregate is an array or a class ([class]) with
(1.1) no user-declared or inherited constructors ([class.ctor]),
(1.2) no private or protected direct non-static data members ([class.access]),
(1.3) no virtual functions ([class.virtual]), and
(1.4) no virtual, private, or protected base classes ([class.mi]).

See the C++20 standard, dcl.init.aggr#1

I'm wondering if we can test for these requirements without compiler magic.

Definitely Possible

The polymorphism part of 1.3 and 1.4 is covered by std::is_polymorphic, which exploits the fact that dynamic_cast is only valid for polymorphic classes.

Probably Impossible

How can we test whether out bases classes are inherited-from privately? And how can we do so for our data members? There are no reflections that would list all of our members or bases classes, let alone their access specifiers.

But the requirement I'm most interested in is 1.1, which would need to detect if we have no user-declared constructors. Even an explicitly defaulted constructor is user-declared.

struct Aggregate {};
struct NonAggregate { NonAggregate() = default; };

How can we possibly distinguish Aggregate and NonAggregate? We would need an expression that is ill-formed for one but not for the other, then use SFINAE. However, both can be default-initialized and value-initialized. See Compiler Explorer to confirm that NonAggregate is indeed not an aggregate type (since C++20).

Jan Schultke
  • 17,446
  • 6
  • 47
  • 96
  • 1
    "I'm wondering if we can test for these requirements without compiler magic." - Why would anyone need this? – Jodocus Jul 14 '21 at 10:40
  • 1
    @Jodocus perhaps if one wanted to implement their own standard library that's more self-hosted. I'm mainly asking this question out of curiosity. – Jan Schultke Jul 14 '21 at 10:43
  • 2
    That would be a hopeless endeavour. There are many more type trait templates that require compiler intrinsics, think about stuff as `std::is_empty`. I do not think that you can make a *complete* implementation of the C++20 standard library without compiler support. – Jodocus Jul 14 '21 at 10:56

0 Answers0