C++17: Direct vs Copy List Initialization

C++11 introduced the uniform initialization syntax using braced initializer lists. You have direct list initialization which does not include an equal sign, for example:

int myInt{42};

and you have copy list initialization which uses the equal sign, for example:

int myInt = {42};

The auto type deduction rules have changes in C++17. With C++17, if you use copy list initialization, then an initializer_list<> is deduced, for example:

auto initList1 = {42};
auto initList2 = {42, 84, 126};

All values in the braced initializer list must be of the same type. The following does not compile:

auto initList2 = {42, 84.42};

When you use direct list initialization, then a value is deduced. For example, the following deduces an int:

auto anInt{42};

This also means that the following causes a compilation error because more than 1 initialization value is given:

auto ints{42, 84, 126};

This is the new C++17 behavior. With C++11/C++14, all of the above would deduce to an initializer_list<int>.

This changed behavior is included since Microsoft Visual C++ 2015.

Share

4 Comments so far »

  1. Jack B said,

    Wrote on August 10, 2017 @ 6:28 am

    I think the examples have got it backwards.

    Re ’auto’ the rules are:

    – for copy list initialization auto deduction will deduce a std::initializer_list if all elements in the list have the same type, or be ill-formed.
    – for direct list initialization auto deduction will deduce a T if the list has a single element, or be ill-formed if there is more than one element.

  2. Marc Gregoire said,

    Wrote on August 10, 2017 @ 1:19 pm

    Yes, you are correct. Don’t know how that slipped in 🙁

    I have corrected the article, and included the fact that all values in the braced initializer list need to have the same type.

  3. srinivasa rao kanaparthi said,

    Wrote on August 25, 2018 @ 4:59 pm

    From the statement “This is the new C++17 behavior. With C++11/C++14, all of the above would deduce to an initializer_list.”

    I didn’t expect the below errors in C++ 11/14 compiler, but I am getting to my surprise.

    C:\Users\Vishnu\Desktop\cpp14.cpp|15|error: unable to deduce ‘std::initializer_list’ from ‘{42, 8.4420000000000002e+1}’|
    C:\Users\Vishnu\Desktop\cpp14.cpp|19|note: for deduction to ‘std::initializer_list’, use copy-list-initialization (i.e. add ‘=’ before the ‘{‘)|

    Are these rules enforced in C++ 11/14 or specific to only C++ 17?

  4. Marc Gregoire said,

    Wrote on August 29, 2018 @ 12:44 pm

    All the elements in an initializer list must be of the same type. In your list, you have an int and a double. Please try with two ints or two doubles.

Comment RSS · TrackBack URI

Leave a Comment

Name: (Required)

E-mail: (Required)

Website:

Comment: