2

I want initialize base class with std::initializer_list.

struct A : public std::array<int, 4>
{
  // This constructor works fine
  A()
  : std::array<int, 4>{{ 1, 2, 3, 4 }}
  {
  }

  // THIS CONSTRUCTOR FAILS TO COMPILE
  A(std::initializer_list<int> il)
  : std::array<int, 4>{il}
  {
  }
};

GCC error for second constructor is

error: array must be initialized with a brace-enclosed initializer

What I want is to initialize new A instance with initializer_list like this

A var{{ 1, 2, 3, 4 }}

and pass it to base class.

2 Answers2

2

The class std::array has no constructor taking a std::initializer_list.

The only way you have is to do it like this :

#include <array>
#include <initializer_list>

struct A : public std::array<int, 4>
{
    A()
    : std::array<int, 4>{{ 1, 2, 3, 4 }}
    {
    }

    A(std::array<int, 4> il)
    : std::array<int, 4>(il)
    {
    }
};

int main ()
{
    A a ({{ 1, 2, 3, 4 }});
}
Chnossos
  • 9,971
  • 4
  • 28
  • 40
  • seems like std::initializer_list is implicitly casted to std::array here. Would this have a runtime performance impact? – user3528030 Apr 13 '14 at 02:08
  • It is not a std::initializer_list that is used here : `std::array` uses [aggregate_initialization](http://en.cppreference.com/w/cpp/language/aggregate_initialization). Quoting [cppreference](http://en.cppreference.com/w/cpp/container/array) : _[std::array] combines the performance and accessibility of a C-style array with the benefits of a standard container [...]_ – Chnossos Apr 13 '14 at 02:10
  • @Chnossos, Although an array can be initialized with list initialization, it cannot be initialized with an actual `initializer_list` object. Try: `auto il = {1,2,3}; array a(il);` – ooga Apr 13 '14 at 02:26
  • So should we use aggregate_initialization for fixed size things and initializer_list for variable sized things then? – user3528030 Apr 13 '14 at 02:28
  • @ShitImplementor You can only use an initializer_list object if there's a ctor that accepts one. As for the performance penalty, with move constructors it shouldn't be a problem. – ooga Apr 13 '14 at 02:30
  • So, to overcome that even tiny performance impact, I could also make std::array a member. Than I'd need to initialize with three braces like `A a{{{..}}};` and add wrapper around `operator[]`, which is an ugly solution. – user3528030 Apr 13 '14 at 02:41
  • Forget about this performance impact. Compilers nowadays are smart enough to speed things like that up. I'm more worried about the fact that you're inheriting from an std container. – Chnossos Apr 13 '14 at 10:22
  • Why? Is it a bad practice to inherit from a container? – user3528030 Apr 13 '14 at 15:19
  • Yes it is a bad practice. I won't elaborate in a comment, so you'd better read [that answer](http://stackoverflow.com/a/7110262/3460805). – Chnossos Apr 13 '14 at 16:35
0

It's saying that an array can be initialized with a "brace-enclosed initializer" as in your first ctor, but not with an initializer_list as in your second. There is no array ctor that takes an initializer_list. In fact, there are no ctors for arrays except for the implicitly-declared special member functions.

ooga
  • 15,423
  • 2
  • 20
  • 21