1

Why does inheriting constructors from a base class break aggregate initialization?

For example, this works:

struct MyArray : std::array<int, 2ul> {};

MyArray a{1, 2};

but this doesn't work:

struct MyArray : std::array<int, 2ul>
{
     using std::array<int, 2ul>::array;
};

MyArray a{1, 2};
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
rnorthcott
  • 77
  • 1
  • 5
  • Why do you expect it to work? The point of an aggregate is that it doesn't have any constructors (default/copy/move aside). Would you expect `MyArray a{1, 2};` then to be aggregate-initialization or to do overload resolution against the (inherited) constructors instead? – user17732522 Jun 07 '22 at 04:57
  • 1
    Wait a second... `std:: array` doesn't HAVE a constructor. Does `using std::array::array;` make any sense at all? – user4581301 Jun 07 '22 at 05:15
  • 1
    `std::array` has a [implicitly generated ctor](https://en.cppreference.com/w/cpp/container/array) @user4581301 – TheScore Jun 07 '22 at 05:50
  • 1
    @user4581301 `std::array` has implicit default, copy and move constructors. – Aykhan Hagverdili Jun 07 '22 at 06:03
  • Good points, but it doesn't have a constructor that will eat an `initializer_list`, so it's not useless in the general case, but is useless here. I wonder if the rationale for the no inherited constructors rule is is an inherited constructor is or can't be easily distinguished from a user-defined constructor. – user4581301 Jun 07 '22 at 16:52

1 Answers1

0

Since C++17, aggregates can have base classes, so that for such structures being derived from other classes/structures list initialization is allowed:

struct MoreData : Data {
    bool done;
};

MoreData y{{"test1", 6.778}, false};

In C++17 an aggregate is defined as

  • either an array
  • or a class type (class, struct, or union) with:
    • no user-declared or explicit constructor
    • no constructor inherited by a using declaration
    • no private or protected non-static data members
    • no virtual functions
    • no virtual, private, or protected base classes

For more details you can refer to Chapter 4 Aggregate Extensions from C++17 - The Complete Guide By Nicolai M. Josuttis

Aamir
  • 1,974
  • 1
  • 14
  • 18
  • On second thought, this is how to get around the problem, not an explanation of WHY it's a problem. – user4581301 Jun 07 '22 at 05:38
  • I feel like this does answer my question, so thanks. `no constructor inherited by a using declaration` – rnorthcott Jun 07 '22 at 07:00
  • Dang, If I'd known, "Because them's the rules" was all you were looking for, I would have answered myself. Still not sure what got this answer a downvote, though. – user4581301 Jun 07 '22 at 17:13