Search code examples
c++c++11language-lawyerinitializer-list

Why does an explicitly declared constructor prevent member initialisation with a C++ 11 initialisation list?


I want to initialize a struct with an initialisation list like this:

struct S
{
    int a;
    int b;

    // S() : a(0), b(0){}  // uncommenting will cause compile error: 
                           // error C2440: 'initializing' : cannot convert from 'initializer-list' to 'S'

    // S(int aArg, int bArg) : a(aArg), b(bArg) {}    // adding this removes the error
}

int main()
{
    S s{1,2};   // initialise with list
}

Is there a good reason, why the explicitly declared default constructor will cause the error? I thought the initialisation lists where introduced to spare the programmer from writing tedious code like the second constructor.


Solution

  • Aggregate initialization - as the name implies - only works for aggregates. Adding a non-trivial constructor to a class makes it a non-aggregate. [dcl.init.list]/3:

    List-initialization of an object or reference of type T is defined as follows:
    — If the initializer list has no elements and T is a class type with a default constructor, the object is value-initialized.
    — Otherwise, if T is an aggregate, aggregate initialization is performed (8.5.1).
    — Otherwise, […]

    And

    An aggregate is an array or a class (Clause 9) with no user-provided constructors (12.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.

    Once your class isn't an aggregate anymore, list-initialization will look for a constructor to call, not the members to initialize.

    The reason is quite simple: If a class has non-trivial constructors, the only way to validly initialize an object of that class type is to call one of the constructors for that object. Initializing a class object without a corresponding constructor would be a devastating design failure.