Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is std::is_aggregate<T> an aggregate?

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?

like image 486
x432ph Avatar asked Apr 23 '19 14:04

x432ph


2 Answers

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

like image 76
NathanOliver Avatar answered Sep 30 '22 19:09

NathanOliver


Since C++17, classes with non-virtual, not private or protected bases are aggregates: https://en.cppreference.com/w/cpp/language/aggregate_initialization

like image 36
SergeyA Avatar answered Sep 30 '22 20:09

SergeyA