From 9eb18fdf9ebc49e52119055a52af7312f3d6eef4 Mon Sep 17 00:00:00 2001 From: Bjarne Stroustrup Date: Tue, 23 May 2017 15:03:52 -0400 Subject: [PATCH] vector exception to {} initializers --- CppCoreGuidelines.md | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 4abed4f..8db3898 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -1,6 +1,6 @@ # C++ Core Guidelines -May 22, 2017 +May 23, 2017 Editors: @@ -11968,6 +11968,43 @@ Whe unambiguous, the `T` can be left out of `T{e}`. The constructuction notation is the most general [initializer notation](#Res-list). +##### Exception + +`std::vector` and other containers were defined before we had `{}` as a notation for construction. +Consider: + + vector vs {10}; // ten empty strings + vector vi1 {1,2,3,4,5,6,7,8,9,10}; // ten elements 1..10 + vector vi2 {10}; // one element with the value 10 + +How do we get a `vector` of 10 default initialized `int`s? + + vector v3(10); // ten elements with value 0 + +The use of `()` rather than `{}` for number of elements is conventional (going back to the early 1980s), hard to change, but still +a design error: for a container where the element type can be confused with the number of elements, we have an ambiguity that +must be resolved. +The conventional resolution is to interpret `{10}` as a list of one element and use `(10)` to distinguish a size. + +This mistake need not be repeated in new code. +We can define a type to represent the number of elements: + + struct Count { int n }; + + template + class Vector { + public: + Vector(Count n); // n default-initialized elements + Vector(initializer_list init); // init.size() elements + // ... + }; + + Vector v1{10}; + Vector v2{Count{10}}; + Vector v3{Count{10}}; // yes, there is still a very minor problem + +The main problem left is to find a suitable name for `Count`. + ##### Enforcement Flag the C-style `(T)e` and functional-style `T(e)` casts.