From dd67c99f1f711d8b3f07e981965658ee119ec2a1 Mon Sep 17 00:00:00 2001 From: Bjarne Stroustrup Date: Sat, 13 Oct 2018 12:03:32 -0400 Subject: [PATCH] made C.con a bit less incomplate More will eventually come --- CppCoreGuidelines.md | 159 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 157 insertions(+), 2 deletions(-) diff --git a/CppCoreGuidelines.md b/CppCoreGuidelines.md index 2df538f..b5f6e83 100644 --- a/CppCoreGuidelines.md +++ b/CppCoreGuidelines.md @@ -6547,12 +6547,167 @@ Summary of container rules: * [C.102: Give a container move operations](#Rcon-move) * [C.103: Give a container an initializer list constructor](#Rcon-init) * [C.104: Give a container a default constructor that sets it to empty](#Rcon-empty) -* [C.105: Give a constructor and `Extent` constructor](#Rcon-val) * ??? -* [C.109: If a resource handle has pointer semantics, provide `*` and `->`](#rcon-ptr) +* [C.109: If a resource handle has pointer semantics, provide `*` and `->`](#Rcon-ptr) **See also**: [Resources](#S-resource) + +### C.100: Follow the STL when defining a container + +##### Reason + +The STL containers are familiar to most C++ programmers and a fundamentally sound design. + +##### Note + +There are of course other fundamentally sound design styles and sometimes reasons to depart from +the style of the standard library, but in the absence of a solid reason to differ, it is simpler +and easier for both implementers and users to follow the standard. + +In particular, `std::vector` and `std::map` provide useful relatively simple models. + +##### Example + + // simplified (e.g., no allocators): + + template + class Sorted_vector { + using value_type = T; + // ... iterator types ... + + Sorted_vector() = default; + Sorted_vector(initializer_list); // initializer-list constructor: sort and store + Sorted_vector(const Sorted_vector&) = default; + Sorted_vector(Sorted_vector&&) = default; + Sorted_vector& operator=(const Sorted_vector&) = default; // copy assignment + Sorted_vector& operator=(Sorted_vector&&) = default; // move assignment + ~Sorted_vector() = default; + + Sorted_vector(const std::vector& v); // store and sort + Sorted_vector(std::vector&& v); // sort and "steal representation" + + const T& operator[](int i) { return rep[i]; } + // no non-const direct access to preserve order + + void push_back(const T&); // insert in the righ place (not necessarily at back) + void push_back(T&&); // insert in the righ place (not necessarily at back) + + // ... cbegin(), cend() ... + private: + std::vector rep; // use a std::vector to hold elements + }; + + template bool operator==(const T&); + template bool operator!=(const T&); + // ... + +Here, the STL style is followed, but incompletely. +That's not uncommon. +Provide only as much functionality as makes sense for a specific container. +The key is to define the conventional constructors, assignments, destructors, and iterators +(as meaningful for the specific container) with their conventional semantics. +From that base, the container can be expanded as needed. +Here, special constructors from `std::vector` were added. + +##### Enforcement + +??? + +### C.101: Give a container value semantics + +##### Reason + +Regular objects are simpler to think and reason about than irregular ones. +Familiarity. + +##### Note + +If meaningful, make a container `Regular` (the concept). +In particular, ensure that an object compared equal to its copy. + +##### Example + + void f(const Sorted_vector& v) + { + Sorted_vector v2 {v}; + if (v!=v2) + cout << "insanity rules!\n"; + // ... + } + +##### Enforcement + +??? + +### C.102: Give a container move operations + +##### Reason + +Containers tend to get large; without a a move constructor and a copy constructor an object can be +expensive to move around, thus tempting people to pass pointers to it around and gettimg into +resource management problems. + +##### Example + + Sorted_vector read_sorted(istream& is) + { + vector v; + cin >> v; // assume we have a read operation for vectors + Sorted_vector sv = v; // sorts + return sv; + } + + A user can reasonably assume that returning a standard-like container is cheap. + +##### Enforcement + +??? + +### C.103: Give a container an initializer list constructor + +##### Reason + +People expect to be able to initialize a container with a set of values. +Familiarity. + +##### Example + + Sotrted_vector sv {1,3,-1,7,0,0}; // Sorted_vector sorts elements as needed + +##### Enforcement + +??? + +### C.104: Give a container a default constructor that sets it to empty + +##### Reason + +To make it `Regular`. + +##### Example + + vector> vs(100); // 100 Sorted_sequences each with the value "" + +##### Enforcement + +??? + +### C.109: If a resource handle has pointer semantics, provide `*` and `->` + +##### Reason + +That's what is expected from pointers. +Familiarity. + +##### Example + + ??? + +##### Enforcement + +??? + ## C.lambdas: Function objects and lambdas A function object is an object supplying an overloaded `()` so that you can call it.