@@ -21,8 +21,8 @@ <h2 id="Background" class="ignoreLink">Background</h2>
21
21
code more bug-prone and harder to read and maintain.</ p >
22
22
23
23
< p > The goal of this guide is to manage this complexity by
24
- describing in detail the dos and don'ts of writing C++ code
25
- . These rules exist to
24
+ describing in detail the dos and don'ts of writing C++
25
+ code . These rules exist to
26
26
keep the code base manageable while still allowing
27
27
coders to use C++ language features productively.</ p >
28
28
@@ -164,9 +164,8 @@ <h3 id="Goals">Goals of the Style Guide</h3>
164
164
165
165
< h2 id ="C++_Version "> C++ Version</ h2 >
166
166
167
- < p > Currently, code should target C++17, i.e., should not use C++2x
168
- features, with the exception of < a href ="#Designated_initializers "> designated
169
- initializers</ a > . The C++ version targeted by this guide will advance
167
+ < p > Currently, code should target C++20, i.e., should not use C++23
168
+ features. The C++ version targeted by this guide will advance
170
169
(aggressively) over time.</ p >
171
170
172
171
@@ -176,7 +175,7 @@ <h2 id="C++_Version">C++ Version</h2>
176
175
177
176
< div >
178
177
< p > Consider portability to other environments before using features
179
- from C++14 and C++17 in your project.</ p >
178
+ from C++17 and C++20 in your project.</ p >
180
179
</ div >
181
180
182
181
< h2 id ="Header_Files "> Header Files</ h2 >
@@ -686,6 +685,11 @@ <h3 id="Namespaces">Namespaces</h3>
686
685
using ::absl::container_internal::ImplementationDetail;
687
686
</ pre >
688
687
</ li >
688
+
689
+ < li > < p > Single-line nested namespace declarations
690
+
691
+ are preferred in new code, but are not required.</ p >
692
+ </ li >
689
693
</ ul >
690
694
691
695
< a id ="Unnamed_Namespaces_and_Static_Variables "> </ a >
@@ -940,14 +944,10 @@ <h4>Decision on initialization</h4>
940
944
941
945
< p > Constant initialization is always allowed. Constant initialization of
942
946
static storage duration variables should be marked with < code > constexpr</ code >
943
- or where possible the
944
-
945
-
946
- < a href ="https://github.com/abseil/abseil-cpp/blob/03c1513538584f4a04d666be5eb469e3979febba/absl/base/attributes.h#L540 ">
947
- < code > ABSL_CONST_INIT</ code > </ a >
948
- attribute. Any non-local static storage
947
+ or < code > constinit</ code > </ p > .
948
+ Any non-local static storage
949
949
duration variable that is not so marked should be presumed to have
950
- dynamic initialization, and reviewed very carefully.</ p >
950
+ dynamic initialization, and reviewed very carefully.
951
951
952
952
< p > By contrast, the following initializations are problematic:</ p >
953
953
@@ -1466,9 +1466,9 @@ <h3 id="Structs_vs._Classes">Structs vs. Classes</h3>
1466
1466
be present; however, these methods must not require or enforce any
1467
1467
invariants.</ p >
1468
1468
1469
- < p > If more functionality or invariants are required, a
1470
- < code > class</ code > is more appropriate. If in doubt, make
1471
- it a < code > class </ code > . </ p >
1469
+ < p > If more functionality or invariants are required, or struct has wide visibility and expected to
1470
+ evolve, then a < code > class</ code > is more appropriate. If in doubt, make it a < code > class </ code > .
1471
+ </ p >
1472
1472
1473
1473
< p > For consistency with STL, you can use
1474
1474
< code > struct</ code > instead of < code > class</ code > for
@@ -1678,17 +1678,23 @@ <h3 id="Operator_Overloading">Operator Overloading</h3>
1678
1678
because they must satisfy this rule for any possible template
1679
1679
arguments. If you define an operator, also define
1680
1680
any related operators that make sense, and make sure they
1681
- are defined consistently. For example, if you overload
1682
- < code > <</ code > , overload all the comparison operators,
1683
- and make sure < code > <</ code > and < code > ></ code > never
1684
- return true for the same arguments.</ p >
1681
+ are defined consistently.</ p >
1685
1682
1686
1683
< p > Prefer to define non-modifying binary operators as
1687
1684
non-member functions. If a binary operator is defined as a
1688
1685
class member, implicit conversions will apply to the
1689
1686
right-hand argument, but not the left-hand one. It will
1690
- confuse your users if < code > a < b</ code > compiles but
1691
- < code > b < a</ code > doesn't.</ p >
1687
+ confuse your users if < code > a + b</ code > compiles but
1688
+ < code > b + a</ code > doesn't.</ p >
1689
+
1690
+ < p > For a type < code > T</ code > whose values can be compared for
1691
+ equality, define a non-member < code > operator==</ code > and document when
1692
+ two values of type < code > T</ code > are considered equal.
1693
+ If there is a single obvious notion of when a value < code > t1</ code >
1694
+ of type < code > T</ code > is less than another such value < code > t2</ code > then
1695
+ you may also define < code > operator<=></ code > , which should be
1696
+ consistent with < code > operator==</ code > .
1697
+ Prefer not to overload the other comparison and ordering operators.</ p >
1692
1698
1693
1699
< p > Don't go out of your way to avoid defining operator
1694
1700
overloads. For example, prefer to define < code > ==</ code > ,
@@ -2874,18 +2880,22 @@ <h4>Where to put the const</h4>
2874
2880
< code > const</ code > first, we do not require it. But be
2875
2881
consistent with the code around you!</ p >
2876
2882
2877
- < h3 id ="Use_of_constexpr "> Use of constexpr</ h3 >
2883
+ < h3 id ="Use_of_constexpr "> Use of constexpr, constinit, and consteval </ h3 >
2878
2884
2879
2885
< p > Use < code > constexpr</ code > to define true
2880
- constants or to ensure constant initialization.</ p >
2886
+ constants or to ensure constant initialization.
2887
+ Use < code > constinit</ code > to ensure constant
2888
+ initialization for non-constant variables.
2889
+ </ p >
2881
2890
2882
2891
< p class ="definition "> </ p >
2883
2892
< p > Some variables can be declared < code > constexpr</ code >
2884
2893
to indicate the variables are true constants, i.e., fixed at
2885
2894
compilation/link time. Some functions and constructors
2886
2895
can be declared < code > constexpr</ code > which enables them
2887
2896
to be used in defining a < code > constexpr</ code >
2888
- variable.</ p >
2897
+ variable. Functions can be declared < code > consteval</ code >
2898
+ to restrict their use to compile time.</ p >
2889
2899
2890
2900
< p class ="pros "> </ p >
2891
2901
< p > Use of < code > constexpr</ code > enables definition of
@@ -2906,9 +2916,11 @@ <h3 id="Use_of_constexpr">Use of constexpr</h3>
2906
2916
robust specification of the constant parts of an
2907
2917
interface. Use < code > constexpr</ code > to specify true
2908
2918
constants and the functions that support their
2909
- definitions. Avoid complexifying function definitions to
2919
+ definitions. < code > consteval</ code > may be used for
2920
+ code that must not be invoked at runtime.
2921
+ Avoid complexifying function definitions to
2910
2922
enable their use with < code > constexpr</ code > . Do not use
2911
- < code > constexpr</ code > to force inlining.</ p >
2923
+ < code > constexpr</ code > or < code > consteval </ code > to force inlining.</ p >
2912
2924
2913
2925
< h3 id ="Integer_Types "> Integer Types</ h3 >
2914
2926
@@ -2948,7 +2960,9 @@ <h3 id="Integer_Types">Integer Types</h3>
2948
2960
< code > int64_t</ code > , etc. You should always use
2949
2961
those in preference to < code > short</ code > , < code > unsigned
2950
2962
long long</ code > and the like, when you need a guarantee
2951
- on the size of an integer. Of the built-in integer types, only
2963
+ on the size of an integer. Prefer to omit the < code > std::</ code >
2964
+ prefix for these types, as the extra 5 characters do
2965
+ not merit the added clutter. Of the built-in integer types, only
2952
2966
< code > int</ code > should be used. When appropriate, you
2953
2967
are welcome to use standard type aliases like
2954
2968
< code > size_t</ code > and < code > ptrdiff_t</ code > .</ p >
@@ -3148,7 +3162,6 @@ <h3 id="Preprocessor_Macros">Preprocessor Macros</h3>
3148
3162
< li > Prefer not using < code > ##</ code > to generate
3149
3163
function/class/variable names.</ li >
3150
3164
3151
-
3152
3165
</ ul >
3153
3166
3154
3167
< p > Exporting macros from headers (i.e., defining them in a header
@@ -3525,8 +3538,8 @@ <h3 id="Designated_initializers">Designated Initializers</h3>
3525
3538
3526
3539
< p class ="cons "> </ p >
3527
3540
< p > While designated initializers have long been part of the C standard and
3528
- supported by C++ compilers as an extension, only recently have they made it
3529
- into the C++ standard, being added as part of C++20.</ p >
3541
+ supported by C++ compilers as an extension, they were not supported by
3542
+ C++ prior to C++20.</ p >
3530
3543
3531
3544
< p > The rules in the C++ standard are stricter than in C and compiler extensions,
3532
3545
requiring that the designated initializers appear in the same order as the
@@ -3768,6 +3781,113 @@ <h3 id="Template_metaprogramming">Template Metaprogramming</h3>
3768
3781
be tweaked as necessary so that the error messages are understandable
3769
3782
and actionable from a user point of view.</ p >
3770
3783
3784
+ < h3 id ="Concepts "> Concepts and Constraints</ h3 >
3785
+
3786
+ < p > Use concepts sparingly.
3787
+ In general, concepts and constraints should only be used in cases
3788
+ where templates would have been used prior to C++20.
3789
+ Avoid introducing new concepts in headers,
3790
+ unless the headers are marked as internal to the library.
3791
+ Do not define concepts that are not enforced by the compiler.
3792
+ Prefer constraints over template metaprogramming, and
3793
+ avoid the < code > template<< i > Concept</ i > T></ code > syntax;
3794
+ instead, use the < code > requires(< i > Concept<T></ i > )</ code >
3795
+ syntax.</ p >
3796
+
3797
+ < p class ="definition "> </ p >
3798
+ < p > The < code > concept</ code > keyword is a new mechanism for defining
3799
+ requirements (such as type traits or interface specifications)
3800
+ for a template parameter.
3801
+ The < code > requires</ code > keyword provides mechanisms for placing
3802
+ anonymous constraints on templates and verifying that constraints
3803
+ are satisfied at compile time.
3804
+ Concepts and constraints are often used together, but can be
3805
+ also used independently.</ p >
3806
+
3807
+ < p class ="pros "> </ p >
3808
+ < ul >
3809
+ < li > Concepts allow the compiler to generate much better error
3810
+ messages when templates are involved, which can reduce confusion
3811
+ and significantly improve the development experience.</ li >
3812
+ < li > Concepts can reduce the boilerplate necessary for defining
3813
+ and using compile-time constraints, often increasing the clarity
3814
+ of the resulting code.</ li >
3815
+ < li > Constraints provide some capabilities that are difficult to
3816
+ achieve with templates and SFINAE techniques.</ li >
3817
+ </ ul >
3818
+
3819
+ < p class ="cons "> </ p >
3820
+ < ul >
3821
+ < li > As with templates, concepts can make code significantly more
3822
+ complex and difficult to understand.</ li >
3823
+ < li > Concept syntax can be confusing to readers, as concepts
3824
+ appear similar to class types at their usage sites.</ li >
3825
+ < li > Concepts, especially at API boundaries, increase code
3826
+ coupling, rigidity, and ossification.</ li >
3827
+ < li > Concepts and constraints can replicate logic from a function
3828
+ body, resulting in code duplication and increased maintenance
3829
+ costs.</ li >
3830
+ < li > Concepts muddy the source of truth for their underlying
3831
+ contracts, as they are standalone named entities that can be
3832
+ utilized in multiple locations, all of which evolve separately
3833
+ from each other.
3834
+ This can cause the stated and implied requirements to diverge
3835
+ over time.</ li >
3836
+ < li > Concepts and constraints affect overload resolution in novel
3837
+ and non-obvious ways.</ li >
3838
+ < li > As with SFINAE, constraints make it harder to refactor code
3839
+ at scale.</ li >
3840
+ </ ul >
3841
+
3842
+ < p class ="decision "> </ p >
3843
+ < p > Predefined concepts in the standard library should be
3844
+ preferred to type traits, when equivalent ones exist.
3845
+ (e.g., if < code > std::is_integral_v</ code > would have been used
3846
+ before C++20, then < code > std::integral</ code > should be used in
3847
+ C++20 code.)
3848
+ Similarly, prefer modern constraint syntax
3849
+ (via < code > requires(< i > Condition</ i > )</ code > ).
3850
+ Avoid legacy template metaprogramming constructs
3851
+ (such as < code > std::enable_if<< i > Condition</ i > ></ code > )
3852
+ as well as the < code > template<< i > Concept</ i > T></ code >
3853
+ syntax.</ p >
3854
+
3855
+ < p > Do not manually re-implement any existing concepts or traits.
3856
+ For example, use
3857
+ < code > requires(std::default_initializable<T>)</ code >
3858
+ instead of
3859
+ < code > requires(requires { T v; })</ code >
3860
+ or the like.
3861
+
3862
+ </ p > < p > New < code > concept</ code > declarations should be rare, and only
3863
+ defined internally within a library, such that they are not
3864
+ exposed at API boundaries.
3865
+ More generally, do not use concepts or constraints in cases where
3866
+ you wouldn't use their legacy template equivalents in C++17.
3867
+ </ p >
3868
+
3869
+ < p > Do not define concepts that duplicate the function body,
3870
+ or impose requirements that would be insignificant or obvious
3871
+ from reading the body of the code or the resulting error messages.
3872
+ For example, avoid the following:
3873
+ </ p > < pre class ="badcode "> template <typename T> // Bad - redundant with negligible benefit
3874
+ concept Addable = std::copyable<T> && requires(T a, T b) { a + b; };
3875
+ template <Addable T>
3876
+ T Add(T x, T y, T z) { return x + y + z; }
3877
+ </ pre >
3878
+ Instead, prefer to leave code as an ordinary template unless
3879
+ you can demonstrate that concepts result in significant
3880
+ improvement for that particular case, such as in the resulting
3881
+ error messages for a deeply nested or non-obvious
3882
+ requirement.
3883
+
3884
+ < p > Concepts should be statically verifiable by the compiler.
3885
+ Do not use any concept whose primary benefits would come from a
3886
+ semantic (or otherwise unenforced) constraint.
3887
+ Requirements that are unenforced at compile time should instead
3888
+ be imposed via other mechanisms such as comments, assertions,
3889
+ or tests.</ p >
3890
+
3771
3891
< h3 id ="Boost "> Boost</ h3 >
3772
3892
3773
3893
< p > Use only approved libraries from the Boost library
@@ -3955,9 +4075,10 @@ <h3 id="Aliases">Aliases</h3>
3955
4075
3956
4076
< p class ="definition "> </ p >
3957
4077
< p > There are several ways to create names that are aliases of other entities:</ p >
3958
- < pre > typedef Foo Bar;
3959
- using Bar = Foo;
3960
- using other_namespace::Foo;
4078
+ < pre > using Bar = Foo;
4079
+ typedef Foo Bar; // But prefer `using` in C++ code.
4080
+ using ::other_namespace::Foo;
4081
+ using enum MyEnumType; // Creates aliases for all enumerators in MyEnumType.
3961
4082
</ pre >
3962
4083
3963
4084
< p > In new code, < code > using</ code > is preferable to < code > typedef</ code > ,
@@ -4308,9 +4429,10 @@ <h3 id="Constant_Names">Constant Names</h3>
4308
4429
4309
4430
< p > All such variables with static storage duration (i.e., statics and globals,
4310
4431
see < a href ="http://en.cppreference.com/w/cpp/language/storage_duration#Storage_duration ">
4311
- Storage Duration</ a > for details) should be named this way. This
4312
- convention is optional for variables of other storage classes, e.g., automatic
4313
- variables; otherwise the usual variable naming rules apply. For example:</ p >
4432
+ Storage Duration</ a > for details) should be named this way, including those in templates where
4433
+ different instantiations of the template may have different values. This convention is optional for
4434
+ variables of other storage classes, e.g., automatic variables; otherwise the usual variable naming
4435
+ rules apply. For example:</ p >
4314
4436
4315
4437
< pre > void ComputeFoo(absl::string_view suffix) {
4316
4438
// Either of these is acceptable.
@@ -4515,7 +4637,7 @@ <h3 id="File_Comments">File Comments</h3>
4515
4637
New files should usually not contain copyright notice or
4516
4638
author line.</ p >
4517
4639
4518
- < h3 id ="Class_Comments "> Class Comments</ h3 >
4640
+ < h3 id ="Class_Comments "> Struct and Class Comments</ h3 >
4519
4641
4520
4642
< p > Every non-obvious class or struct declaration should have an
4521
4643
accompanying comment that describes what it is for and how it should
@@ -4532,6 +4654,8 @@ <h3 id="Class_Comments">Class Comments</h3>
4532
4654
};
4533
4655
</ pre >
4534
4656
4657
+ < h4 id ="Class_Comments_Details "> Class Comments</ h4 >
4658
+
4535
4659
< p > The class comment should provide the reader with enough information to know
4536
4660
how and when to use the class, as well as any additional considerations
4537
4661
necessary to correctly use the class. Document the synchronization assumptions
@@ -4925,7 +5049,8 @@ <h3 id="Non-ASCII_Characters">Non-ASCII Characters</h3>
4925
5049
< p > When possible, avoid the < code > u8</ code > prefix.
4926
5050
It has significantly different semantics starting in C++20
4927
5051
than in C++17, producing arrays of < code > char8_t</ code >
4928
- rather than < code > char</ code > .
5052
+ rather than < code > char</ code > , and will change again in C++23.
5053
+
4929
5054
4930
5055
</ p > < p > You shouldn't use < code > char16_t</ code > and
4931
5056
< code > char32_t</ code > character types, since they're for
0 commit comments