mirror of
https://github.com/google/styleguide.git
synced 2024-03-22 13:11:43 +08:00
Update C++ styleguide
- add section for inclusive language. - move include-what-you-use to a new section. - clarify usage of absl::optional for by-value vs by-reference params. - document usage of `` as a code-indexing hint - note that enclosing identifiers in `` can help code indexers.
This commit is contained in:
parent
8416dda837
commit
3919c347aa
203
cppguide.html
203
cppguide.html
|
@ -247,14 +247,37 @@ guard:</p>
|
|||
|
||||
|
||||
|
||||
<h3 id="Include_What_You_Use">Include What You Use</h3>
|
||||
|
||||
<p>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.
|
||||
</p>
|
||||
|
||||
<p>Do not rely on transitive inclusions. This allows people to remove
|
||||
no-longer-needed <code>#include</code> statements from their headers without
|
||||
breaking clients. This also applies to related headers
|
||||
- <code>foo.cc</code> should include <code>bar.h</code> if it uses a
|
||||
symbol from it even if <code>foo.h</code>
|
||||
includes <code>bar.h</code>.</p>
|
||||
|
||||
<h3 id="Forward_Declarations">Forward Declarations</h3>
|
||||
|
||||
<p>Avoid using forward declarations where possible.
|
||||
Instead, <code>#include</code> the headers you need.</p>
|
||||
Instead, <a href="#Include_What_You_Use">include the headers you need</a>.
|
||||
</p>
|
||||
|
||||
|
||||
<p class="definition"></p>
|
||||
<p>A "forward declaration" is a declaration of a class,
|
||||
function, or template without an associated definition.</p>
|
||||
<p>A "forward declaration" is a declaration of an entity
|
||||
without an associated definition.</p>
|
||||
<pre>// In a C++ source file:
|
||||
class B;
|
||||
void FuncInB();
|
||||
extern int variable_in_b;
|
||||
ABSL_DECLARE_FLAG(flag_in_b);
|
||||
</pre>
|
||||
|
||||
<p class="pros"></p>
|
||||
<ul>
|
||||
|
@ -274,6 +297,10 @@ function, or template without an associated definition.</p>
|
|||
user code to skip necessary recompilation when headers
|
||||
change.</li>
|
||||
|
||||
<li>A forward declaration as opposed to an #include statement
|
||||
makes it difficult for automatic tooling to discover the module
|
||||
defining the symbol.</li>
|
||||
|
||||
<li>A forward declaration may be broken by subsequent
|
||||
changes to the library. Forward declarations of functions
|
||||
and templates can prevent the header owners from making
|
||||
|
@ -316,19 +343,8 @@ void test(D* x) { f(x); } // calls f(B*)
|
|||
</ul>
|
||||
|
||||
<p class="decision"></p>
|
||||
<ul>
|
||||
<li>Try to avoid forward declarations of entities
|
||||
defined in another project.</li>
|
||||
|
||||
<li>When using a function declared in a header file,
|
||||
always <code>#include</code> that header.</li>
|
||||
|
||||
<li>When using a class template, prefer to
|
||||
<code>#include</code> its header file.</li>
|
||||
</ul>
|
||||
|
||||
<p>Please see <a href="#Names_and_Order_of_Includes">Names and Order
|
||||
of Includes</a> for rules about when to #include a header.</p>
|
||||
Try to avoid forward declarations of entities
|
||||
defined in another project.
|
||||
|
||||
<h3 id="Inline_Functions">Inline Functions</h3>
|
||||
|
||||
|
@ -453,14 +469,6 @@ Either style is acceptable, but prefer consistency with existing code.</p>
|
|||
alphabetically. Note that older code might not conform to
|
||||
this rule and should be fixed when convenient.</p>
|
||||
|
||||
<p>You should include all the headers that define the symbols you rely
|
||||
upon, except in the unusual case of <a href="#Forward_Declarations">forward
|
||||
declaration</a>. If you rely on symbols from <code>bar.h</code>,
|
||||
don't count on the fact that you included <code>foo.h</code> which
|
||||
(currently) includes <code>bar.h</code>: include <code>bar.h</code>
|
||||
yourself, unless <code>foo.h</code> explicitly demonstrates its intent
|
||||
to provide you the symbols of <code>bar.h</code>.</p>
|
||||
|
||||
<p>For example, the includes in
|
||||
|
||||
<code>google-awesome-project/src/foo/internal/fooserver.cc</code>
|
||||
|
@ -563,7 +571,7 @@ namespaces, this can add a lot of clutter.</p>
|
|||
|
||||
<ul>
|
||||
<li>Follow the rules on <a href="#Namespace_Names">Namespace Names</a>.
|
||||
</li><li>Terminate namespaces with comments as shown in the given examples.
|
||||
</li><li>Terminate multi-line namespaces with comments as shown in the given examples.
|
||||
</li><li>
|
||||
|
||||
<p>Namespaces wrap the entire source file after
|
||||
|
@ -1316,11 +1324,12 @@ declaring and/or deleting the appropriate operations in the <code>public</code>
|
|||
section of the declaration.</p>
|
||||
|
||||
<p>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.</p>
|
||||
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.</p>
|
||||
|
||||
<pre>class Copyable {
|
||||
public:
|
||||
|
@ -1328,12 +1337,13 @@ must also provide the corresponding constructor.</p>
|
|||
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 @@ a return value and sometimes via output parameters (or in/out parameters).</p>
|
|||
improve readability, and often provide the same or better
|
||||
performance.</p>
|
||||
|
||||
<p>Parameters are either input to the function, output from the
|
||||
<p>Parameters are either inputs to the function, outputs from the
|
||||
function, or both. Input parameters should usually be values
|
||||
or <code>const</code> references,
|
||||
while required (non-nullable) output and input/output parameters should
|
||||
usually be references. Generally, use <code>absl::optional</code> to represent
|
||||
optional inputs, and non-<code>const</code> pointers to represent
|
||||
or <code>const</code> references, while non-optional output and
|
||||
input/output parameters should usually be references (which cannot be null).
|
||||
Generally, use <code>absl::optional</code> to represent optional by-value
|
||||
inputs, and use a <code>const</code> pointer when the non-optional form would
|
||||
have used a reference. Use non-<code>const</code> pointers to represent
|
||||
optional outputs.</p>
|
||||
|
||||
<p>
|
||||
|
@ -1722,7 +1733,7 @@ Avoid defining functions that require a <code>const</code> reference parameter
|
|||
to outlive the call, because <code>const</code> reference parameters bind
|
||||
to temporaries. Instead, find a way to eliminate the lifetime requirement
|
||||
(for example, by copying the parameter), or pass it by <code>const</code>
|
||||
pointer and document the non-null requirement.
|
||||
pointer and document the lifetime and non-null requirements.
|
||||
|
||||
</p>
|
||||
|
||||
|
@ -2394,12 +2405,12 @@ functions throwing and make it unconditionally
|
|||
<h3 id="Run-Time_Type_Information__RTTI_">Run-Time Type
|
||||
Information (RTTI)</h3>
|
||||
|
||||
<p>Avoid using Run Time Type Information (RTTI).</p>
|
||||
<p>Avoid using run-time type information (RTTI).</p>
|
||||
|
||||
<p class="definition"></p>
|
||||
<p> RTTI allows a
|
||||
programmer to query the C++ class of an object at run
|
||||
time. This is done by use of <code>typeid</code> or
|
||||
programmer to query the C++ class of an object at
|
||||
run-time. This is done by use of <code>typeid</code> or
|
||||
<code>dynamic_cast</code>.</p>
|
||||
|
||||
<p class="pros"></p>
|
||||
|
@ -3126,8 +3137,8 @@ memset(&data, 0, sizeof(data));
|
|||
}
|
||||
</pre>
|
||||
|
||||
<a name="auto"></a>
|
||||
<h3 id="Type_deduction">Type deduction</h3>
|
||||
<a id="auto"></a>
|
||||
<h3 id="Type_deduction">Type Deduction (including auto)</h3>
|
||||
|
||||
<p>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 @@ std::array numbers = {4, 8, 15, 16, 23, 42};</pre>
|
|||
key type aren't relevant, but the type of the values is probably useful.
|
||||
In such situations, it's often possible to define local variables with
|
||||
explicit types that convey the relevant information:
|
||||
</p><pre class="goodcode">auto it = my_map_.find(key);
|
||||
if (it != my_map_.end()) {
|
||||
</p><pre class="goodcode">if (auto it = my_map_.find(key); it != my_map_.end()) {
|
||||
WidgetWithBellsAndWhistles& widget = *it->second;
|
||||
// Do stuff with `widget`
|
||||
}</pre>
|
||||
|
@ -3367,7 +3377,7 @@ if (it != my_map_.end()) {
|
|||
As with function parameter comments, this can enable tools to detect if
|
||||
you get the order of the fields wrong.
|
||||
|
||||
<h3 id="CTAD">Class template argument deduction</h3>
|
||||
<h3 id="CTAD">Class Template Argument Deduction</h3>
|
||||
|
||||
<p>Use class template argument deduction only with templates that have
|
||||
explicitly opted into supporting it.</p>
|
||||
|
@ -3425,7 +3435,7 @@ array(T, U...) -> std::array<T, 1 + sizeof...(U)>;
|
|||
<p>Uses of CTAD must also follow the general rules on
|
||||
<a href="#Type_deduction">Type deduction</a>.</p>
|
||||
|
||||
<h3 id="Designated_initializers">Designated initializers</h3>
|
||||
<h3 id="Designated_initializers">Designated Initializers</h3>
|
||||
|
||||
<p>Use designated initializers only in their C++20-compliant form.</p>
|
||||
|
||||
|
@ -3471,7 +3481,7 @@ fields appear in the struct definition.</p>
|
|||
|
||||
|
||||
|
||||
<h3 id="Lambda_expressions">Lambda expressions</h3>
|
||||
<h3 id="Lambda_expressions">Lambda Expressions</h3>
|
||||
|
||||
<p>Use lambda expressions where appropriate. Prefer explicit captures
|
||||
when the lambda will escape the current scope.</p>
|
||||
|
@ -3625,7 +3635,7 @@ complex lambdas with default capture by value.
|
|||
|
||||
</ul>
|
||||
|
||||
<h3 id="Template_metaprogramming">Template metaprogramming</h3>
|
||||
<h3 id="Template_metaprogramming">Template Metaprogramming</h3>
|
||||
|
||||
<p>Avoid complicated template programming.</p>
|
||||
|
||||
|
@ -3639,7 +3649,7 @@ computation in the type domain.</p>
|
|||
<p>Template metaprogramming allows extremely flexible interfaces that
|
||||
are type safe and high performance. Facilities like
|
||||
|
||||
<a href="https://code.google.com/p/googletest/">Google Test</a>,
|
||||
<a href="https://github.com/google/googletest">Google Test</a>,
|
||||
<code>std::tuple</code>, <code>std::function</code>, and
|
||||
Boost.Spirit would be impossible without it.</p>
|
||||
|
||||
|
@ -3795,8 +3805,6 @@ features to the list, so this list may be expanded in
|
|||
the future.</p>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<h3 id="std_hash">std::hash</h3>
|
||||
|
||||
<p>Do not define specializations of <code>std::hash</code>.</p>
|
||||
|
@ -3870,7 +3878,7 @@ using a new customization mechanism that doesn't have the drawbacks of
|
|||
|
||||
|
||||
|
||||
<h3 id="Other_Features"><a name="C++11">Other C++ Features</a></h3>
|
||||
<h3 id="Other_Features"><a id="C++11">Other C++ Features</a></h3>
|
||||
|
||||
<p>As with <a href="#Boost">Boost</a>, some modern C++
|
||||
extensions encourage coding practices that hamper
|
||||
|
@ -4029,6 +4037,21 @@ typedef unordered_set<DataPoint, hash<DataPoint>, DataPointComparator&g
|
|||
using ::foo::Bar;
|
||||
</pre>
|
||||
|
||||
<h2 id="Inclusive_Language">Inclusive Language</h2>
|
||||
|
||||
<p>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
|
||||
(<a href="https://apastyle.apa.org/style-grammar-guidelines/grammar/singular-they">even
|
||||
when singular</a>), and "it"/"its" for software, computers, and other
|
||||
things that aren't people.</p>
|
||||
|
||||
|
||||
|
||||
<h2 id="Naming">Naming</h2>
|
||||
|
||||
<p>The most important consistency rules are those that govern
|
||||
|
@ -4270,8 +4293,8 @@ set_count(int count)</code>.</p>
|
|||
|
||||
<h3 id="Namespace_Names">Namespace Names</h3>
|
||||
|
||||
Namespace names are all lower-case. Top-level namespace names are
|
||||
based on the project name
|
||||
Namespace names are all lower-case, with words separated by underscores.
|
||||
Top-level namespace names are based on the project name
|
||||
. Avoid collisions
|
||||
between nested namespaces and well-known top-level namespaces.
|
||||
|
||||
|
@ -4446,11 +4469,10 @@ be used.</p>
|
|||
|
||||
<pre>// 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 @@ left to comments in the function definition.</p>
|
|||
declaration:</p>
|
||||
|
||||
<ul>
|
||||
<li>What the inputs and outputs are.</li>
|
||||
<li>What the inputs and outputs are. If function argument names
|
||||
are provided in `backticks`, then code-indexing
|
||||
tools may be able to present the documentation better.</li>
|
||||
|
||||
<li>For class member functions: whether the object
|
||||
remembers reference arguments beyond the duration of
|
||||
|
@ -4516,21 +4540,16 @@ declaration:</p>
|
|||
|
||||
<p>Here is an example:</p>
|
||||
|
||||
<pre>// 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.
|
||||
<pre>// 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;
|
||||
</pre>
|
||||
|
||||
<p>However, do not be unnecessarily verbose or state the
|
||||
|
@ -4699,8 +4718,7 @@ the code does what it does, or make the code self describing.</p>
|
|||
Compare this:
|
||||
|
||||
<pre class="badcode">// 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);
|
||||
}
|
||||
</pre>
|
||||
|
@ -4708,8 +4726,7 @@ if (iter != v.end()) {
|
|||
To this:
|
||||
|
||||
<pre>// 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);
|
||||
}
|
||||
</pre>
|
||||
|
@ -5018,10 +5035,10 @@ ampersand (&) and the variable name.</p>
|
|||
auto x_plus_n = [&x](int n) -> int { return x + n; }
|
||||
</pre>
|
||||
<p>Short lambdas may be written inline as function arguments.</p>
|
||||
<pre>std::set<int> blacklist = {7, 8, 9};
|
||||
<pre>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());
|
||||
</pre>
|
||||
|
@ -5124,8 +5141,8 @@ my_widget.Transform(x1, x2, x3,
|
|||
|
||||
<h3 id="Braced_Initializer_List_Format">Braced Initializer List Format</h3>
|
||||
|
||||
<p>Format a <a href="#Braced_Initializer_List">braced initializer list</a>
|
||||
exactly like you would format a function call in its place.</p>
|
||||
<p>Format a braced initializer list exactly like you would format a function
|
||||
call in its place.</p>
|
||||
|
||||
<p>If the braced list follows a name (e.g., a type or
|
||||
variable name), format as if the <code>{}</code> were the
|
||||
|
@ -5146,7 +5163,7 @@ SomeType variable{
|
|||
{"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 @@ MyType m = { // Here, you could also break before {.
|
|||
|
||||
<h3 id="Conditionals">Conditionals</h3>
|
||||
|
||||
<p>The <code>if</code> and <code>else</code> keywords belong on separate lines.
|
||||
There should be a space between the <code>if</code> and the open parenthesis,
|
||||
and between the close parenthesis and the curly brace (if any), but no space
|
||||
between the parentheses and the condition.</p>
|
||||
<p>Each of <code>if</code>, <code>else</code>, and <code>else if</code>
|
||||
belong on separate lines. There should be a space between
|
||||
the <code>if</code> and the open parenthesis, and between the close
|
||||
parenthesis and the curly brace (if any), but no space between the
|
||||
parentheses and the condition.</p>
|
||||
|
||||
<pre>if (condition) { // no spaces inside parentheses
|
||||
... // 2 space indent.
|
||||
|
@ -5219,8 +5237,9 @@ if (condition) {
|
|||
</pre>
|
||||
|
||||
<p>However, if one part of an
|
||||
<code>if</code>-<code>else</code> statement uses curly
|
||||
braces, the other part must too:</p>
|
||||
<code>if</code>-<code>else</code> or an
|
||||
<code>if</code>-<code>else if</code>-<code>else</code> statement uses curly
|
||||
braces, the other part(s) must, too:</p>
|
||||
|
||||
<pre class="badcode">// Not allowed - curly on IF but not ELSE
|
||||
if (condition) {
|
||||
|
@ -5236,10 +5255,12 @@ else {
|
|||
}
|
||||
</pre>
|
||||
|
||||
<pre>// Curly braces around both IF and ELSE required because
|
||||
<pre>// 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 @@ x = r->y;
|
|||
<code>*</code> or <code>&</code>.</li>
|
||||
</ul>
|
||||
|
||||
<p>When declaring a pointer variable or argument, you may
|
||||
place the asterisk adjacent to either the type or to the
|
||||
<p>When declaring a pointer or reference variable or argument, you may
|
||||
place the asterisk/ampersand adjacent to either the type or the
|
||||
variable name:</p>
|
||||
|
||||
<pre>// These are fine, space preceding.
|
||||
|
@ -5385,6 +5406,7 @@ reference decorations. Such declarations are easily misread.
|
|||
int x, y;
|
||||
</pre>
|
||||
<pre class="badcode">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 &
|
||||
</pre>
|
||||
|
@ -5440,9 +5462,6 @@ return(result); // return is not a function!
|
|||
|
||||
<h3 id="Variable_and_Array_Initialization">Variable and Array Initialization</h3>
|
||||
|
||||
<p>Your choice of <code>=</code>, <code>()</code>, or
|
||||
<code>{}</code>.</p>
|
||||
|
||||
<p>You may choose between <code>=</code>,
|
||||
<code>()</code>, and <code>{}</code>; the following are
|
||||
all correct:</p>
|
||||
|
|
Loading…
Reference in New Issue
Block a user