1

In C++ standard for std::array it says:

An array is an aggregate (8.5.1) that can be initialized with the syntax

array a = { initializer-list };

where initializer-list is a comma-separated list of up to N elements whose types are convertible to T.

Also it says that std::array is an aggregate type and its constructors are implicitly generated.

To initialize an std::array with an initializer list it must have a constructor taking an std::initializer_list as an argument.

Is a constructor that takes an std::initializer_list also implicitly generated for user-defined types or it is specific to std::array?

3
  • 3
    I think you're confusing initializer-list and std::initializer_ist. One is a grammatical term, the other is a type. You have misquoted the typography of the standard! Commented Sep 11, 2015 at 11:08
  • The type of an initializer-list is std::initializer_list. There should be a constructor taking std::initializer_list. Commented Sep 11, 2015 at 11:12
  • 3
    "The type of an initializer-list is std::initializer_list" No it is not, as Kerrek just explained. In this context, initializer-list simply is "a comma-separated list of up to N elements whose types are convertible to T". Commented Sep 11, 2015 at 11:18

3 Answers 3

6

No, the compiler does not generate a constructor taking an std::initializer_list, neither for std::array nor for any other aggregate type.

What you observe here is aggregate initialization which is completely unrelated to std::initializer_list.

The term "initializer-list" in the standard snippet you provided refers to a list of initializers, which again has nothing to do with std::initializer_list.

You can test that with something like this:

struct A {
    int i;
    std::string str;
};

int main() {
    A a{1, "asdf"};
}

This works, but clearly does not make use of std::initializer_list since that can only handle a single type at once.

Sign up to request clarification or add additional context in comments.

Comments

1

Edit:

The syntax works for aggregate types,

#include <iostream>
using namespace std;

struct A {
    int a;
    int b;
    int get_a() {return a;}
};

int main() {
    A a1({4,5});
    A a2{1,2};
    cout << a1.a << '\n';
    cout << a2.b << '\n';
    return 0;
}

Live

But technically for aggregate types there is no constructor created. Those invocations present two forms of list initialization. Since T is an aggregate, it falls for the aggregate initialization related bullet.

Comments

1

std::array is aggregate and so aggregate-initialization is used, and no constructor that receives std::initializer_list is generated.

If the initializer is a (non-parenthesized) braced-init-list, the object or reference is list-initialized (8.5.4).

List-initialization is initialization of an object or reference from a braced-init-list. Such an initializer is called an initializer list, and the comma-separated initializer-clauses of the list are called the elements of the initializer list.

List-initialization of an object or reference of type T is defined as follows:

If T is an aggregate, aggregate initialization is performed (8.5.1).

When an aggregate is initialized by an initializer list, as specified in 8.5.4, the elements of the initializer list are taken as initializers for the members of the aggregate, in increasing subscript or member order. Each member is copy-initialized from the corresponding initializer-clause.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.