I always was under the impression that types like std::is_same
, std::is_void
, or std::is_aggregate
are supposed to inherit from std::integral_constant
, or more specifically from std::bool_constant
.
However, aggregate classes must not have a base class by definition, but when I use these types as T
in std::is_aggregate_v<T>
, I get true
. So apparently, they are not derived from std::bool_constant
?
So my question is:
Why is std::is_aggregate_v<std::is_aggregate<void>>
true, at least with GCC and Clang? Doesn't the standard specify that std::is_aggregate
is derived from std::bool_constant
? If not, does this mean it leaves the value of the above line as an implementation detail?
However, aggregate classes must not have a base class by definition
This is no longer true. [dcl.init.aggr]/1 defines an aggregate as
An aggregate is an array or a class with
no user-provided, explicit, or inherited constructors ([class.ctor]),
no private or protected non-static data members (Clause [class.access]),
no virtual functions, and
no virtual, private, or protected base classes ([class.mi]).
[ Note: Aggregate initialization does not allow accessing protected and private base class' members or constructors. — end note ]
There is no longer a condition that it does not have a base class like it did in C++14 and earlier. As long as it has a public, non virtual base class that is now allowed. This means that the type traits are now considered aggregates as long as the above holds true for them
Since C++17, classes with non-virtual, not private or protected bases are aggregates: https://en.cppreference.com/w/cpp/language/aggregate_initialization
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With