The features of C++17 were a big step in the history of C++ and brought a lot of new features. In C++17, there are new auto rules for direct-list-initialization. This feature in C++, changes the rules for auto deduction from a braced-init-list. In this post, we explain what these new rules for auto deduction with examples are.
Table of Contents
What is auto keyword in C++?
The auto
keyword arrives with the new features in C++11 and improved in C++17, can be used as a placeholder type specifier (an auto-typed variable), or it can be used in function declaration, or in a structured binding declaration. The auto
keyword can be used with other new CLANG standards like C++14, C++17, etc.
What are the new rules for auto deduction in C++ 17?
In C++17, For copy-list-initialization, the auto deduction will either deduce a std::initializer_list (if the types of entries in the braced-init-list are all identical) or be ill-formed otherwise.
Note that, auto a = {1, 2, 3}, b = {1};
remains unchanged and deduces initializer_list<int>
. This change is intended as a defect resolution against C++14.
Now, let’s see the examples below.
Auto deduction from braced-init-list Rule #1
For direct list-initialization: For a braced-init-list with only a single element, the auto deduction will deduce from that entry. In the example below, there is a single member in the braced-init-list, and this is automatically defined as an initializer_list that consists of int members.
1 2 3 4 5 |
auto a = { 30 }; // decltype(a) is std::initializer_list<int> for (auto i : a) std::cout << i << ","; std::cout << std::endl << std::endl; |
Auto deduction from braced-init-list Rule #2
For direct list-initialization: For copy-list-initialization, auto deduction will either deduce a std::initializer_list (if the types of entries in the braced-init-list are all identical) or be ill-formed otherwise. For a braced-init list with more than one element, the auto deduction will be ill-formed. Here is an example of creating an initilizer_list with an auto keyword,
1 2 3 4 5 |
auto b = { 10 , 20 }; // decltype(b) is std::initializer_list<int> for (auto i : b) std::cout << i << ","; std::cout << std::endl << std::endl; |
Here above, a
is automatically defined as an initializer_list
that consists with int
members, std::initializer_list<int>.
1 2 3 4 5 |
auto bb = { 1.5f , 2.5f }; // decltype(bb) is std::initializer_list<float> for (auto i : bb) std::cout << i << ","; std::cout << std::endl << std::endl; |
Here above, aa is automatically defined as an initializer_list
that consists with float
members, std::initializer_list<float>.
Example below, gives error, because there are multiple element types (int and float), according to above “types of entries in the braced-init-list are all should be identical”
1 2 3 |
auto bbb = { 1 , 2.0 }; // error: not a single element |
Auto deduction from braced-init-list Rule #3
For copy-list-initialization, auto deduction will either deduce a std::initializer_list. If the initialization is direct-list-initialization then the braced-init-list shall contain only a single initializer-clause L
.
Before the C++17, auto a{1, 2, 3}, b{1};
was allowed and both variables were of type initializer_list<int>
. Now auto a{1, 2, 3};
is ill-formed and auto b{1};
declares an int
.
In this example below, c
is declared as an int
type,
1 2 3 4 |
auto c{ 40 }; // decltype(c) is int std::cout << c << std::endl; |
in this concept, we can only list a single member, here example below gives error,
1 2 3 |
// auto c{ 1, 2 }; // error: not a single element |
Is there a full example about auto deduction from braced-init-list in C++ 17?
Here is a full example about auto deduction from braced-init-list in C++17,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
#include <iostream> int main() { //Rule #1 auto a = { 30 }; // decltype(b) is std::initializer_list<int> for (auto i : a) std::cout << i << ","; std::cout << std::endl << std::endl; //Rule #2 auto b = { 10 , 20 }; // decltype(a) is std::initializer_list<int> for (auto i : b) std::cout << i << ","; std::cout << std::endl << std::endl; auto bb = { 1.5f , 2.5f }; // decltype(aa) is std::initializer_list<float> for (auto i : bb) std::cout << i << ","; std::cout << std::endl << std::endl; // auto bbb = { 1, 2.0 }; // error: cannot deduce element type //Rule #3 auto c{ 40 }; // decltype(c) is int std::cout << c << std::endl; // auto cc{ 1, 2 }; // error: not a single element system("pause"); return 0; } |
For more details, please see this https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3922.html
C++ Builder is the easiest and fastest C and C++ compiler and IDE for building simple or professional applications on the Windows operating system. It is also easy for beginners to learn with its wide range of samples, tutorials, help files, and LSP support for code. RAD Studio’s C++ Builder version comes with the award-winning VCL framework for high-performance native Windows apps and the powerful FireMonkey (FMX) framework for UIs.
There is a free C++ Builder Community Edition for students, beginners, and startups; it can be downloaded from here. For professional developers, there are Professional, Architect, or Enterprise versions of C++ Builder and there is a trial version you can download from here.