diff --git a/cppguide.html b/cppguide.html index c6dce95df..6c52c111c 100644 --- a/cppguide.html +++ b/cppguide.html @@ -247,14 +247,37 @@
If a source or header file refers to a symbol defined elsewhere, +the file should directly include a header file which properly intends +to provide a declaration or definition of that symbol. It should not +include header files for any other reason. +
+ +Do not rely on transitive inclusions. This allows people to remove
+no-longer-needed #include
statements from their headers without
+breaking clients. This also applies to related headers
+- foo.cc
should include bar.h
if it uses a
+symbol from it even if foo.h
+includes bar.h
.
Avoid using forward declarations where possible.
-Instead, #include
the headers you need.
A "forward declaration" is a declaration of a class, -function, or template without an associated definition.
+A "forward declaration" is a declaration of an entity + without an associated definition.
+// In a C++ source file: +class B; +void FuncInB(); +extern int variable_in_b; +ABSL_DECLARE_FLAG(flag_in_b); +
#include
that header.#include
its header file.Please see Names and Order -of Includes for rules about when to #include a header.
+Try to avoid forward declarations of entities +defined in another project.You should include all the headers that define the symbols you rely
-upon, except in the unusual case of forward
-declaration. If you rely on symbols from bar.h
,
-don't count on the fact that you included foo.h
which
-(currently) includes bar.h
: include bar.h
-yourself, unless foo.h
explicitly demonstrates its intent
-to provide you the symbols of bar.h
.
For example, the includes in
google-awesome-project/src/foo/internal/fooserver.cc
@@ -563,7 +571,7 @@
Namespaces wrap the entire source file after @@ -1316,11 +1324,12 @@
Specifically, a copyable class should explicitly declare the copy -operations, a move-only class should explicitly declare the move operations, -and a non-copyable/movable class should explicitly delete the copy operations. -Explicitly declaring or deleting all four copy/move operations is permitted, -but not required. If you provide a copy or move assignment operator, you -must also provide the corresponding constructor.
+operations, a move-only class should explicitly declare the move operations, and +a non-copyable/movable class should explicitly delete the copy operations. A +copyable class may also declare move operations in order to support efficient +moves. Explicitly declaring or deleting all four copy/move operations is +permitted, but not required. If you provide a copy or move assignment operator, +you must also provide the corresponding constructor.class Copyable { public: @@ -1328,12 +1337,13 @@- -Copyable and Movable Types
Copyable& operator=(const Copyable& other) = default; // The implicit move operations are suppressed by the declarations above. + // You may explicitly declare move operations to support efficient moves. }; class MoveOnly { public: - MoveOnly(MoveOnly&& other); - MoveOnly& operator=(MoveOnly&& other); + MoveOnly(MoveOnly&& other) = default; + MoveOnly& operator=(MoveOnly&& other) = default; // The copy operations are implicitly deleted, but you can // spell that out explicitly if you want: @@ -1709,12 +1719,13 @@Inputs and Outputs
improve readability, and often provide the same or better performance. -Parameters are either input to the function, output from the +
Parameters are either inputs to the function, outputs from the function, or both. Input parameters should usually be values -or
const
references, -while required (non-nullable) output and input/output parameters should -usually be references. Generally, useabsl::optional
to represent -optional inputs, and non-const
pointers to represent +orconst
references, while non-optional output and +input/output parameters should usually be references (which cannot be null). +Generally, useabsl::optional
to represent optional by-value +inputs, and use aconst
pointer when the non-optional form would +have used a reference. Use non-const
pointers to represent optional outputs.@@ -1722,7 +1733,7 @@
Inputs and Outputs
to outlive the call, becauseconst
reference parameters bind to temporaries. Instead, find a way to eliminate the lifetime requirement (for example, by copying the parameter), or pass it byconst
-pointer and document the non-null requirement. +pointer and document the lifetime and non-null requirements. @@ -2394,12 +2405,12 @@
noexcept
Run-Time Type Information (RTTI)
-Avoid using Run Time Type Information (RTTI).
+Avoid using run-time type information (RTTI).
RTTI allows a -programmer to query the C++ class of an object at run -time. This is done by use of
@@ -3126,8 +3137,8 @@typeid
or +programmer to query the C++ class of an object at +run-time. This is done by use oftypeid
ordynamic_cast
.sizeof
}
Use type deduction only if it makes the code clearer to readers who aren't familiar with the project, or if it makes the code safer. Do not use it @@ -3300,8 +3311,7 @@
auto it = my_map_.find(key); -if (it != my_map_.end()) { +if (auto it = my_map_.find(key); it != my_map_.end()) { WidgetWithBellsAndWhistles& widget = *it->second; // Do stuff with `widget` }@@ -3367,7 +3377,7 @@Structured bindings
As with function parameter comments, this can enable tools to detect if you get the order of the fields wrong. -Class template argument deduction
+Class Template Argument Deduction
Use class template argument deduction only with templates that have explicitly opted into supporting it.
@@ -3425,7 +3435,7 @@Class template argument deduction
Uses of CTAD must also follow the general rules on Type deduction.
-Designated initializers
+Designated Initializers
Use designated initializers only in their C++20-compliant form.
@@ -3471,7 +3481,7 @@Designated initializers
-Lambda expressions
+Lambda Expressions
Use lambda expressions where appropriate. Prefer explicit captures when the lambda will escape the current scope.
@@ -3625,7 +3635,7 @@Lambda expressions
Avoid complicated template programming.
@@ -3639,7 +3649,7 @@Template metaprogramming allows extremely flexible interfaces that
are type safe and high performance. Facilities like
-Google Test,
+Google Test,
std::tuple
, std::function
, and
Boost.Spirit would be impossible without it.
Do not define specializations of std::hash
.
As with Boost, some modern C++ extensions encourage coding practices that hamper @@ -4029,6 +4037,21 @@
In all code, including naming and comments, use inclusive language +and avoid terms that other programmers might find disrespectful or offensive +(such as "master" and "slave", "blacklist" and "whitelist", or "redline"), +even if the terms also have an ostensibly neutral meaning. +Similarly, use gender-neutral language unless you're referring +to a specific person (and using their preferred pronouns). For example, +use "they"/"them"/"their" for people of unspecified gender +(even +when singular), and "it"/"its" for software, computers, and other +things that aren't people.
+ + +The most important consistency rules are those that govern @@ -4270,8 +4293,8 @@
// Iterates over the contents of a GargantuanTable. // Example: -// GargantuanTableIterator* iter = table->NewIterator(); +// std::unique_ptr<GargantuanTableIterator> iter = table->NewIterator(); // for (iter->Seek("foo"); !iter->done(); iter->Next()) { // process(iter->key(), iter->value()); // } -// delete iter; class GargantuanTableIterator { ... }; @@ -4494,7 +4516,9 @@Function Declarations
declaration:
Here is an example:
-// Returns an iterator for this table. It is the client's -// responsibility to delete the iterator when it is done with it, -// and it must not use the iterator once the GargantuanTable object -// on which the iterator was created has been deleted. -// -// The iterator is initially positioned at the beginning of the table. +// Returns an iterator for this table, positioned at the first entry +// lexically greater than or equal to `start_word`. If there is no +// such entry, returns a null pointer. The client must not use the +// iterator after the underlying GargantuanTable has been destroyed. // // This method is equivalent to: -// Iterator* iter = table->NewIterator(); -// iter->Seek(""); +// std::unique_ptr<Iterator> iter = table->NewIterator(); +// iter->Seek(start_word); // return iter; -// If you are going to immediately seek to another place in the -// returned iterator, it will be faster to use NewIterator() -// and avoid the extra seek. -Iterator* GetIterator() const; +std::unique_ptr<Iterator> GetIterator(absl::string_view start_word) const;However, do not be unnecessarily verbose or state the @@ -4699,8 +4718,7 @@
Don'ts
Compare this:// Find the element in the vector. <-- Bad: obvious! -auto iter = std::find(v.begin(), v.end(), element); -if (iter != v.end()) { +if (std::find(v.begin(), v.end(), element) != v.end()) { Process(element); }@@ -4708,8 +4726,7 @@Don'ts
To this:// Process "element" unless it was already processed. -auto iter = std::find(v.begin(), v.end(), element); -if (iter != v.end()) { +if (std::find(v.begin(), v.end(), element) != v.end()) { Process(element); }@@ -5018,10 +5035,10 @@Lambda Expressions
auto x_plus_n = [&x](int n) -> int { return x + n; }
Short lambdas may be written inline as function arguments.
-std::set<int> blacklist = {7, 8, 9}; +std::set<int> to_remove = {7, 8, 9}; std::vector<int> digits = {3, 9, 1, 8, 4, 7, 1}; -digits.erase(std::remove_if(digits.begin(), digits.end(), [&blacklist](int i) { - return blacklist.find(i) != blacklist.end(); +digits.erase(std::remove_if(digits.begin(), digits.end(), [&to_remove](int i) { + return to_remove.find(i) != to_remove.end(); }), digits.end());@@ -5124,8 +5141,8 @@Function Calls
Braced Initializer List Format
-Format a braced initializer list -exactly like you would format a function call in its place.
+Format a braced initializer list exactly like you would format a function +call in its place.
If the braced list follows a name (e.g., a type or variable name), format as if the
{}
were the @@ -5146,7 +5163,7 @@Braced Initializer List Format
{"assume a zero-length name before {"}, SomeOtherType{ "Very long string requiring the surrounding breaks.", - some, other values}, + some, other, values}, SomeOtherType{"Slightly shorter string", some, other, values}}; SomeType variable{ @@ -5161,10 +5178,11 @@Braced Initializer List Format
Conditionals
-The
+if
andelse
keywords belong on separate lines. - There should be a space between theif
and the open parenthesis, - and between the close parenthesis and the curly brace (if any), but no space - between the parentheses and the condition.Each of
if
,else
, andelse if
+ belong on separate lines. There should be a space between + theif
and the open parenthesis, and between the close + parenthesis and the curly brace (if any), but no space between the + parentheses and the condition.if (condition) { // no spaces inside parentheses ... // 2 space indent. @@ -5219,8 +5237,9 @@Conditionals
However, if one part of an -
+if
-else
statement uses curly -braces, the other part must too:if
-else
or an +if
-else if
-else
statement uses curly +braces, the other part(s) must, too:// Not allowed - curly on IF but not ELSE if (condition) { @@ -5236,10 +5255,12 @@-Conditionals
}// Curly braces around both IF and ELSE required because +// Curly braces around IF, ELSE IF, and ELSE required because // one of the clauses used braces. if (condition) { foo; +} else if (other_condition) { + frob; } else { bar; } @@ -5360,8 +5381,8 @@Pointer and Reference Expressions
* or&
.
When declaring a pointer variable or argument, you may -place the asterisk adjacent to either the type or to the +
When declaring a pointer or reference variable or argument, you may +place the asterisk/ampersand adjacent to either the type or the variable name:
// These are fine, space preceding. @@ -5385,6 +5406,7 @@Pointer and Reference Expressions
int x, *y; // Disallowed - no & or * in multiple declaration +int* x, *y; // Disallowed - no & or * in multiple declaration; inconsistent spacing char * c; // Bad - spaces on both sides of * const std::string & str; // Bad - spaces on both sides of &@@ -5440,9 +5462,6 @@Return Values
Variable and Array Initialization
-Your choice of
-=
,()
, or -{}
.You may choose between
=
,()
, and{}
; the following are all correct: