C++17 New Rules For auto Deduction From braced-init-list

Initialization of variables in C++ can have several forms:

C++11 introduced a generalized syntax for initialization with a braced initializer list, referred to as braced-init-list. Initialization with braced-init-list is called list initialization. There are two types of list initialization, each having multiple forms (check the above links), but simplified, we can have:

  • direct list initialization: T object {arg1, arg2, ...};
  • copy list initialization: T object = {arg1, arg2, ...};

Prior to C++17 the type for all the following objects (a, b, c and d) is deduced to std::initializer_list<int>. There is no difference between the direct-list-initialization and the copy-list-initialization on the result of the type deduction.

auto a = {42};   // std::initializer_list<int>
auto b {42};     // std::initializer_list<int>
auto c = {1, 2}; // std::initializer_list<int>
auto d {1, 2};   // std::initializer_list<int>

This, however, changed in C++17 that introduced the following rules:

  • for copy list initialization auto deduction will deduce a std::initializer_list<T> 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.

As a result, the example above changes so that a and c are still std::initializer_list<int> but b is deduced as an int and d is ill-formed, because there is more than one value in the brace-init-list.

auto a = {42};   // std::initializer_list<int>
auto b {42};     // int
auto c = {1, 2}; // std::initializer_list<int>
auto d {1, 2};   // error, too many 

For more information about these changes see N3922: New Rules for auto deduction from braced-init-list.

3 Replies to “C++17 New Rules For auto Deduction From braced-init-list”

  1. So currently clang and gcc apply this change to C++11 and C++14, see Wandbox for latest versions of both: https://wandbox.org/ . The proposal noted that this was considered a C++14 defect and clangs status for N3922: http://clang.llvm.org/cxx_status.html#n3922 says:

    “This is a backwards-incompatible change that is applied to all language versions that allow type deduction from auto (per the request of the C++ committee)”

    Important to note for those using older compilers since there was implementation divergence here for a bit of time and this caused confusion for some as we can see from this Stackoverflow question: http://stackoverflow.com/q/31301369/1708801

  2. My C++11/14 compiler
    for the line
    auto d {1, 2}; // std::initializer_list
    giving the error
    C:\Users\Vishnu\Desktop\cpp14.cpp|11|error: direct-list-initialization of ‘auto’ requires exactly one element [-fpermissive]|

    From your explanation I thought I will see this error in only C++17, but I am seeing in 11 and 14 as well.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.