mirror of
https://github.com/google/styleguide.git
synced 2024-03-22 13:11:43 +08:00
Update C++ style guide.
Minor formatting and wording fixes.
This commit is contained in:
parent
5120fd6b14
commit
a4413633ec
124
cppguide.html
124
cppguide.html
|
@ -343,8 +343,8 @@ void test(D* x) { f(x); } // calls f(B*)
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p class="decision"></p>
|
<p class="decision"></p>
|
||||||
Try to avoid forward declarations of entities
|
<p>Try to avoid forward declarations of entities
|
||||||
defined in another project.
|
defined in another project.</p>
|
||||||
|
|
||||||
<h3 id="Inline_Functions">Inline Functions</h3>
|
<h3 id="Inline_Functions">Inline Functions</h3>
|
||||||
|
|
||||||
|
@ -512,8 +512,7 @@ should have unique names based on the project name, and possibly
|
||||||
its path. Do not use <i>using-directives</i> (e.g.,
|
its path. Do not use <i>using-directives</i> (e.g.,
|
||||||
<code>using namespace foo</code>). Do not use
|
<code>using namespace foo</code>). Do not use
|
||||||
inline namespaces. For unnamed namespaces, see
|
inline namespaces. For unnamed namespaces, see
|
||||||
<a href="#Unnamed_Namespaces_and_Static_Variables">Unnamed Namespaces and
|
<a href="#Internal_Linkage">Internal Linkage</a>.
|
||||||
Static Variables</a>.
|
|
||||||
|
|
||||||
</p><p class="definition"></p>
|
</p><p class="definition"></p>
|
||||||
<p>Namespaces subdivide the global scope
|
<p>Namespaces subdivide the global scope
|
||||||
|
@ -674,13 +673,13 @@ inline void my_inline_function() {
|
||||||
</li><li>Do not use inline namespaces.</li>
|
</li><li>Do not use inline namespaces.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3 id="Unnamed_Namespaces_and_Static_Variables">Unnamed Namespaces and Static
|
<a id="Unnamed_Namespaces_and_Static_Variables"></a>
|
||||||
Variables</h3>
|
<h3 id="Internal_Linkage">Internal Linkage</h3>
|
||||||
|
|
||||||
<p>When definitions in a <code>.cc</code> file do not need to be
|
<p>When definitions in a <code>.cc</code> file do not need to be
|
||||||
referenced outside that file, place them in an unnamed
|
referenced outside that file, give them internal linkage by placing
|
||||||
namespace or declare them <code>static</code>. Do not use either
|
them in an unnamed namespace or declaring them <code>static</code>.
|
||||||
of these constructs in <code>.h</code> files.
|
Do not use either of these constructs in <code>.h</code> files.
|
||||||
|
|
||||||
</p><p class="definition"></p>
|
</p><p class="definition"></p>
|
||||||
<p>All declarations can be given internal linkage by placing them in unnamed
|
<p>All declarations can be given internal linkage by placing them in unnamed
|
||||||
|
@ -733,7 +732,7 @@ common prefix, and such grouping is usually unnecessary anyway.</p>
|
||||||
|
|
||||||
<p>If you define a nonmember function and it is only
|
<p>If you define a nonmember function and it is only
|
||||||
needed in its <code>.cc</code> file, use
|
needed in its <code>.cc</code> file, use
|
||||||
<a href="#Unnamed_Namespaces_and_Static_Variables">internal linkage</a> to limit
|
<a href="#Internal_Linkage">internal linkage</a> to limit
|
||||||
its scope.</p>
|
its scope.</p>
|
||||||
|
|
||||||
<h3 id="Local_Variables">Local Variables</h3>
|
<h3 id="Local_Variables">Local Variables</h3>
|
||||||
|
@ -1366,8 +1365,8 @@ class NotCopyableOrMovable {
|
||||||
};
|
};
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>These declarations/deletions can be omitted only if they are obvious:
|
<p>These declarations/deletions can be omitted only if they are obvious:</p>
|
||||||
</p><ul>
|
<ul>
|
||||||
<li>If the class has no <code>private</code> section, like a
|
<li>If the class has no <code>private</code> section, like a
|
||||||
<a href="#Structs_vs._Classes">struct</a> or an interface-only base class,
|
<a href="#Structs_vs._Classes">struct</a> or an interface-only base class,
|
||||||
then the copyability/movability can be determined by the
|
then the copyability/movability can be determined by the
|
||||||
|
@ -1723,13 +1722,13 @@ performance.</p>
|
||||||
Avoid returning a pointer unless it can be null.</p>
|
Avoid returning a pointer unless it can be null.</p>
|
||||||
|
|
||||||
<p>Parameters are either inputs to the function, outputs from the
|
<p>Parameters are either inputs to the function, outputs from the
|
||||||
function, or both. Input parameters should usually be values
|
function, or both. Non-optional input parameters should usually be values
|
||||||
or <code>const</code> references, while non-optional output and
|
or <code>const</code> references, while non-optional output and
|
||||||
input/output parameters should usually be references (which cannot be null).
|
input/output parameters should usually be references (which cannot be null).
|
||||||
Generally, use <code>absl::optional</code> to represent optional by-value
|
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
|
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
|
have used a reference. Use non-<code>const</code> pointers to represent
|
||||||
optional outputs.</p>
|
optional outputs and optional input/output parameters.</p>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Avoid defining functions that require a <code>const</code> reference parameter
|
Avoid defining functions that require a <code>const</code> reference parameter
|
||||||
|
@ -2555,7 +2554,8 @@ casts when explicit type conversion is necessary.
|
||||||
|
|
||||||
<li>Use <code>reinterpret_cast</code> to do unsafe conversions of
|
<li>Use <code>reinterpret_cast</code> to do unsafe conversions of
|
||||||
pointer types to and from integer and other pointer
|
pointer types to and from integer and other pointer
|
||||||
types. Use this
|
types,
|
||||||
|
including <code>void*</code>. Use this
|
||||||
only if you know what you are doing and you understand the aliasing
|
only if you know what you are doing and you understand the aliasing
|
||||||
issues. Also, consider the alternative
|
issues. Also, consider the alternative
|
||||||
<code>absl::bit_cast</code>.</li>
|
<code>absl::bit_cast</code>.</li>
|
||||||
|
@ -2701,9 +2701,7 @@ make a copy of the value as it was before the operation.
|
||||||
<p class="cons"></p>
|
<p class="cons"></p>
|
||||||
<p>The tradition developed, in C, of using post-increment, even
|
<p>The tradition developed, in C, of using post-increment, even
|
||||||
when the expression value is not used, especially in
|
when the expression value is not used, especially in
|
||||||
<code>for</code> loops. Some find post-increment easier
|
<code>for</code> loops.</p>
|
||||||
to read, since the "subject" (<code>i</code>) precedes
|
|
||||||
the "verb" (<code>++</code>), just like in English.</p>
|
|
||||||
|
|
||||||
<p class="decision"></p>
|
<p class="decision"></p>
|
||||||
<p>Use prefix increment/decrement, unless the code explicitly
|
<p>Use prefix increment/decrement, unless the code explicitly
|
||||||
|
@ -3294,8 +3292,8 @@ auto i = y.Find(key);
|
||||||
|
|
||||||
<p>For local variables, you can use type deduction to make the code clearer
|
<p>For local variables, you can use type deduction to make the code clearer
|
||||||
by eliminating type information that is obvious or irrelevant, so that
|
by eliminating type information that is obvious or irrelevant, so that
|
||||||
the reader can focus on the meaningful parts of the code:
|
the reader can focus on the meaningful parts of the code:</p>
|
||||||
</p><pre class="neutralcode">std::unique_ptr<WidgetWithBellsAndWhistles> widget_ptr =
|
<pre class="neutralcode">std::unique_ptr<WidgetWithBellsAndWhistles> widget_ptr =
|
||||||
absl::make_unique<WidgetWithBellsAndWhistles>(arg1, arg2);
|
absl::make_unique<WidgetWithBellsAndWhistles>(arg1, arg2);
|
||||||
absl::flat_hash_map<std::string,
|
absl::flat_hash_map<std::string,
|
||||||
std::unique_ptr<WidgetWithBellsAndWhistles>>::const_iterator
|
std::unique_ptr<WidgetWithBellsAndWhistles>>::const_iterator
|
||||||
|
@ -3311,17 +3309,17 @@ std::array numbers = {4, 8, 15, 16, 23, 42};</pre>
|
||||||
type is an iterator, and in many contexts the container type and even the
|
type is an iterator, and in many contexts the container type and even the
|
||||||
key type aren't relevant, but the type of the values is probably useful.
|
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
|
In such situations, it's often possible to define local variables with
|
||||||
explicit types that convey the relevant information:
|
explicit types that convey the relevant information:</p>
|
||||||
</p><pre class="goodcode">if (auto it = my_map_.find(key); it != my_map_.end()) {
|
<pre class="goodcode">if (auto it = my_map_.find(key); it != my_map_.end()) {
|
||||||
WidgetWithBellsAndWhistles& widget = *it->second;
|
WidgetWithBellsAndWhistles& widget = *it->second;
|
||||||
// Do stuff with `widget`
|
// Do stuff with `widget`
|
||||||
}</pre>
|
}</pre>
|
||||||
If the type is a template instance, and the parameters are
|
<p>If the type is a template instance, and the parameters are
|
||||||
boilerplate but the template itself is informative, you can use
|
boilerplate but the template itself is informative, you can use
|
||||||
class template argument deduction to suppress the boilerplate. However,
|
class template argument deduction to suppress the boilerplate. However,
|
||||||
cases where this actually provides a meaningful benefit are quite rare.
|
cases where this actually provides a meaningful benefit are quite rare.
|
||||||
Note that class template argument deduction is also subject to a
|
Note that class template argument deduction is also subject to a
|
||||||
<a href="#CTAD">separate style rule</a>.
|
<a href="#CTAD">separate style rule</a>.</p>
|
||||||
|
|
||||||
<p>Do not use <code>decltype(auto)</code> if a simpler option will work,
|
<p>Do not use <code>decltype(auto)</code> if a simpler option will work,
|
||||||
because it's a fairly obscure feature, so it has a high cost in code
|
because it's a fairly obscure feature, so it has a high cost in code
|
||||||
|
@ -3373,10 +3371,10 @@ std::array numbers = {4, 8, 15, 16, 23, 42};</pre>
|
||||||
this may also mean the names are less recognizable to your reader than the
|
this may also mean the names are less recognizable to your reader than the
|
||||||
field names. We recommend using a comment to indicate the name of the
|
field names. We recommend using a comment to indicate the name of the
|
||||||
underlying field, if it doesn't match the name of the binding, using the
|
underlying field, if it doesn't match the name of the binding, using the
|
||||||
same syntax as for function parameter comments:
|
same syntax as for function parameter comments:</p>
|
||||||
</p><pre>auto [/*field_name1=*/ bound_name1, /*field_name2=*/ bound_name2] = ...</pre>
|
<pre>auto [/*field_name1=*/ bound_name1, /*field_name2=*/ bound_name2] = ...</pre>
|
||||||
As with function parameter comments, this can enable tools to detect if
|
<p>As with function parameter comments, this can enable tools to detect if
|
||||||
you get the order of the fields wrong.
|
you get the order of the fields wrong.</p>
|
||||||
|
|
||||||
<h3 id="CTAD">Class Template Argument Deduction</h3>
|
<h3 id="CTAD">Class Template Argument Deduction</h3>
|
||||||
|
|
||||||
|
@ -3387,21 +3385,21 @@ std::array numbers = {4, 8, 15, 16, 23, 42};</pre>
|
||||||
<p><a href="https://en.cppreference.com/w/cpp/language/class_template_argument_deduction">Class
|
<p><a href="https://en.cppreference.com/w/cpp/language/class_template_argument_deduction">Class
|
||||||
template argument deduction</a> (often abbreviated "CTAD") occurs when
|
template argument deduction</a> (often abbreviated "CTAD") occurs when
|
||||||
a variable is declared with a type that names a template, and the template
|
a variable is declared with a type that names a template, and the template
|
||||||
argument list is not provided (not even empty angle brackets):
|
argument list is not provided (not even empty angle brackets):</p>
|
||||||
</p><pre class="neutralcode">std::array a = {1, 2, 3}; // `a` is a std::array<int, 3></pre>
|
<pre class="neutralcode">std::array a = {1, 2, 3}; // `a` is a std::array<int, 3></pre>
|
||||||
The compiler deduces the arguments from the initializer using the
|
<p>The compiler deduces the arguments from the initializer using the
|
||||||
template's "deduction guides", which can be explicit or implicit.
|
template's "deduction guides", which can be explicit or implicit.</p>
|
||||||
|
|
||||||
<p>Explicit deduction guides look like function declarations with trailing
|
<p>Explicit deduction guides look like function declarations with trailing
|
||||||
return types, except that there's no leading <code>auto</code>, and the
|
return types, except that there's no leading <code>auto</code>, and the
|
||||||
function name is the name of the template. For example, the above example
|
function name is the name of the template. For example, the above example
|
||||||
relies on this deduction guide for <code>std::array</code>:
|
relies on this deduction guide for <code>std::array</code>:</p>
|
||||||
</p><pre class="neutralcode">namespace std {
|
<pre class="neutralcode">namespace std {
|
||||||
template <class T, class... U>
|
template <class T, class... U>
|
||||||
array(T, U...) -> std::array<T, 1 + sizeof...(U)>;
|
array(T, U...) -> std::array<T, 1 + sizeof...(U)>;
|
||||||
}</pre>
|
}</pre>
|
||||||
Constructors in a primary template (as opposed to a template specialization)
|
<p>Constructors in a primary template (as opposed to a template specialization)
|
||||||
also implicitly define deduction guides.
|
also implicitly define deduction guides.</p>
|
||||||
|
|
||||||
<p>When you declare a variable that relies on CTAD, the compiler selects
|
<p>When you declare a variable that relies on CTAD, the compiler selects
|
||||||
a deduction guide using the rules of constructor overload resolution,
|
a deduction guide using the rules of constructor overload resolution,
|
||||||
|
@ -3443,8 +3441,8 @@ array(T, U...) -> std::array<T, 1 + sizeof...(U)>;
|
||||||
<p class="definition"></p>
|
<p class="definition"></p>
|
||||||
<p><a href="https://en.cppreference.com/w/cpp/language/aggregate_initialization#Designated_initializers">
|
<p><a href="https://en.cppreference.com/w/cpp/language/aggregate_initialization#Designated_initializers">
|
||||||
Designated initializers</a> are a syntax that allows for initializing an
|
Designated initializers</a> are a syntax that allows for initializing an
|
||||||
aggregate ("plain old struct") by naming its fields explicitly:
|
aggregate ("plain old struct") by naming its fields explicitly:</p>
|
||||||
</p><pre class="neutralcode"> struct Point {
|
<pre class="neutralcode"> struct Point {
|
||||||
float x = 0.0;
|
float x = 0.0;
|
||||||
float y = 0.0;
|
float y = 0.0;
|
||||||
float z = 0.0;
|
float z = 0.0;
|
||||||
|
@ -3455,9 +3453,9 @@ array(T, U...) -> std::array<T, 1 + sizeof...(U)>;
|
||||||
.y = 2.0,
|
.y = 2.0,
|
||||||
// z will be 0.0
|
// z will be 0.0
|
||||||
};</pre>
|
};</pre>
|
||||||
The explicitly listed fields will be initialized as specified, and others
|
<p>The explicitly listed fields will be initialized as specified, and others
|
||||||
will be initialized in the same way they would be in a traditional aggregate
|
will be initialized in the same way they would be in a traditional aggregate
|
||||||
initialization expression like <code>Point{1.0, 2.0}</code>.
|
initialization expression like <code>Point{1.0, 2.0}</code>.</p>
|
||||||
|
|
||||||
<p class="pros"></p>
|
<p class="pros"></p>
|
||||||
<p>Designated initializers can make for convenient and highly readable
|
<p>Designated initializers can make for convenient and highly readable
|
||||||
|
@ -3525,20 +3523,20 @@ std::sort(indices.begin(), indices.end(), [&](int a, int b) {
|
||||||
|
|
||||||
<p>A variable capture can also have an explicit initializer, which can
|
<p>A variable capture can also have an explicit initializer, which can
|
||||||
be used for capturing move-only variables by value, or for other situations
|
be used for capturing move-only variables by value, or for other situations
|
||||||
not handled by ordinary reference or value captures:
|
not handled by ordinary reference or value captures:</p>
|
||||||
</p><pre>std::unique_ptr<Foo> foo = ...;
|
<pre>std::unique_ptr<Foo> foo = ...;
|
||||||
[foo = std::move(foo)] () {
|
[foo = std::move(foo)] () {
|
||||||
...
|
...
|
||||||
}</pre>
|
}</pre>
|
||||||
Such captures (often called "init captures" or "generalized lambda captures")
|
<p>Such captures (often called "init captures" or "generalized lambda captures")
|
||||||
need not actually "capture" anything from the enclosing scope, or even have
|
need not actually "capture" anything from the enclosing scope, or even have
|
||||||
a name from the enclosing scope; this syntax is a fully general way to define
|
a name from the enclosing scope; this syntax is a fully general way to define
|
||||||
members of a lambda object:
|
members of a lambda object:</p>
|
||||||
<pre class="neutralcode">[foo = std::vector<int>({1, 2, 3})] () {
|
<pre class="neutralcode">[foo = std::vector<int>({1, 2, 3})] () {
|
||||||
...
|
...
|
||||||
}</pre>
|
}</pre>
|
||||||
The type of a capture with an initializer is deduced using the same rules
|
<p>The type of a capture with an initializer is deduced using the same rules
|
||||||
as <code>auto</code>.
|
as <code>auto</code>.</p>
|
||||||
|
|
||||||
<p class="pros"></p>
|
<p class="pros"></p>
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -3881,6 +3879,7 @@ using a new customization mechanism that doesn't have the drawbacks of
|
||||||
|
|
||||||
<h3 id="Other_Features"><a id="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++
|
<p>As with <a href="#Boost">Boost</a>, some modern C++
|
||||||
extensions encourage coding practices that hamper
|
extensions encourage coding practices that hamper
|
||||||
readability—for example by removing
|
readability—for example by removing
|
||||||
|
@ -4013,7 +4012,7 @@ implementation retain some degree of freedom to change the alias.</p>
|
||||||
<pre>namespace mynamespace {
|
<pre>namespace mynamespace {
|
||||||
// Used to store field measurements. DataPoint may change from Bar* to some internal type.
|
// Used to store field measurements. DataPoint may change from Bar* to some internal type.
|
||||||
// Client code should treat it as an opaque pointer.
|
// Client code should treat it as an opaque pointer.
|
||||||
using DataPoint = foo::Bar*;
|
using DataPoint = ::foo::Bar*;
|
||||||
|
|
||||||
// A set of measurements. Just an alias for user convenience.
|
// A set of measurements. Just an alias for user convenience.
|
||||||
using TimeSeries = std::unordered_set<DataPoint, std::hash<DataPoint>, DataPointComparator>;
|
using TimeSeries = std::unordered_set<DataPoint, std::hash<DataPoint>, DataPointComparator>;
|
||||||
|
@ -4319,7 +4318,8 @@ build breaks because of name lookup rules. In particular, do not
|
||||||
create any nested <code>std</code> namespaces. Prefer unique project
|
create any nested <code>std</code> namespaces. Prefer unique project
|
||||||
identifiers
|
identifiers
|
||||||
(<code>websearch::index</code>, <code>websearch::index_util</code>)
|
(<code>websearch::index</code>, <code>websearch::index_util</code>)
|
||||||
over collision-prone names like <code>websearch::util</code>.</p>
|
over collision-prone names like <code>websearch::util</code>. Also avoid overly deep nesting
|
||||||
|
namespaces (<a href="https://abseil.io/tips/130">TotW #130</a>).</p>
|
||||||
|
|
||||||
<p>For <code>internal</code> namespaces, be wary of other code being
|
<p>For <code>internal</code> namespaces, be wary of other code being
|
||||||
added to the same <code>internal</code> namespace causing a collision
|
added to the same <code>internal</code> namespace causing a collision
|
||||||
|
@ -4327,7 +4327,7 @@ added to the same <code>internal</code> namespace causing a collision
|
||||||
collisions). In such a situation, using the filename to make a unique
|
collisions). In such a situation, using the filename to make a unique
|
||||||
internal name is helpful
|
internal name is helpful
|
||||||
(<code>websearch::index::frobber_internal</code> for use
|
(<code>websearch::index::frobber_internal</code> for use
|
||||||
in <code>frobber.h</code>)</p>
|
in <code>frobber.h</code>).</p>
|
||||||
|
|
||||||
<h3 id="Enumerator_Names">Enumerator Names</h3>
|
<h3 id="Enumerator_Names">Enumerator Names</h3>
|
||||||
|
|
||||||
|
@ -4505,11 +4505,10 @@ operation.</p>
|
||||||
<p>Almost every function declaration should have comments immediately
|
<p>Almost every function declaration should have comments immediately
|
||||||
preceding it that describe what the function does and how to use
|
preceding it that describe what the function does and how to use
|
||||||
it. These comments may be omitted only if the function is simple and
|
it. These comments may be omitted only if the function is simple and
|
||||||
obvious (e.g., simple accessors for obvious properties of the
|
obvious (e.g., simple accessors for obvious properties of the class).
|
||||||
class). These comments should open with descriptive verbs in the
|
Function comments should be written with an implied subject of
|
||||||
indicative mood ("Opens the file") rather than verbs in the imperative
|
<i>This function</i> and should start with the verb phrase; for example,
|
||||||
("Open the file"). The comment describes the function; it does not
|
"Opens the file", rather than "Open the file". In general, these comments do not
|
||||||
tell the function what to do. In general, these comments do not
|
|
||||||
describe how the function performs its task. Instead, that should be
|
describe how the function performs its task. Instead, that should be
|
||||||
left to comments in the function definition.</p>
|
left to comments in the function definition.</p>
|
||||||
|
|
||||||
|
@ -5373,22 +5372,27 @@ x = r->y;
|
||||||
<code>*</code> or <code>&</code>.</li>
|
<code>*</code> or <code>&</code>.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<p>When declaring a pointer or reference variable or argument, you may
|
<p>When referring to a pointer or reference (variable declarations or definitions, arguments,
|
||||||
place the asterisk/ampersand adjacent to either the type or the
|
return types, template parameters, etc), you may place the space before or after the
|
||||||
variable name:</p>
|
asterisk/ampersand. In the trailing-space style, the space is elided in some cases (template
|
||||||
|
parameters, etc).</p>
|
||||||
|
|
||||||
<pre>// These are fine, space preceding.
|
<pre>// These are fine, space preceding.
|
||||||
char *c;
|
char *c;
|
||||||
const std::string &str;
|
const std::string &str;
|
||||||
|
int *GetPointer();
|
||||||
|
std::vector<char *>
|
||||||
|
|
||||||
// These are fine, space following.
|
// These are fine, space following (or elided).
|
||||||
char* c;
|
char* c;
|
||||||
const std::string& str;
|
const std::string& str;
|
||||||
|
int* GetPointer();
|
||||||
|
std::vector<char*> // Note no space between '*' and '>'
|
||||||
</pre>
|
</pre>
|
||||||
|
|
||||||
<p>You should do this consistently within a single
|
<p>You should do this consistently within a single
|
||||||
file,
|
file.
|
||||||
so, when modifying an existing file, use the style in
|
When modifying an existing file, use the style in
|
||||||
that file.</p>
|
that file.</p>
|
||||||
|
|
||||||
It is allowed (if unusual) to declare multiple variables in the same
|
It is allowed (if unusual) to declare multiple variables in the same
|
||||||
|
|
Loading…
Reference in New Issue
Block a user