C++ Core Guidelines 完整规则标题索引
配合 中文整理 阅读。按原文顺序保留所有具有数字编号的规则标题,点击编号直达规则正文。
这里是英文标题索引,不是逐条中文翻译;原文标记为 ???、removed 的内容照原样保留。
安全配置中以列表而非标题列出的 Type / Bounds / Lifetime 规则另列于末尾。
来源:原文 Markdown 修订 33bcd015997f0d8e0fa0202eb66254a16f59ad8f;整理于 2026-09-05。
Copyright (c) Standard C++ Foundation and its contributors。授权见 随附文本。
In: Introduction
- In.0: Don’t panic!
P: Philosophy
- P.1: Express ideas directly in code
- P.2: Write in ISO Standard C++
- P.3: Express intent
- P.4: Ideally, a program should be statically type safe
- P.5: Prefer compile-time checking to run-time checking
- P.6: What cannot be checked at compile time should be checkable at run time
- P.7: Catch run-time errors early
- P.8: Don’t leak any resources
- P.9: Don’t waste time or space
- P.10: Prefer immutable data to mutable data
- P.11: Encapsulate messy constructs, rather than spreading through the code
- P.12: Use supporting tools as appropriate
- P.13: Use support libraries as appropriate
I: Interfaces
- I.1: Make interfaces explicit
- I.2: Avoid non-
constglobal variables - I.3: Avoid singletons
- I.4: Make interfaces precisely and strongly typed
- I.5: State preconditions (if any)
- I.6: Prefer
Expects()for expressing preconditions - I.7: State postconditions
- I.8: Prefer
Ensures()for expressing postconditions - I.9: If an interface is a template, document its parameters using concepts
- I.10: Use exceptions to signal a failure to perform a required task
- I.11: Never transfer ownership by a raw pointer (
T*) or reference (T&) - I.12: Declare a pointer that must not be null as
not_null - I.13: Do not pass an array as a single pointer
- I.22: Avoid complex initialization of global objects
- I.23: Keep the number of function arguments low
- I.24: Avoid adjacent parameters that can be invoked by the same arguments in either order with different meaning
- I.25: Prefer empty abstract classes as interfaces to class hierarchies
- I.26: If you want a cross-compiler ABI, use a C-style subset
- I.27: For stable library ABI, consider the Pimpl idiom
- I.30: Encapsulate rule violations
F: Functions
- F.1: “Package” meaningful operations as carefully named functions
- F.2: A function should perform a single logical operation
- F.3: Keep functions short and simple
- F.4: If a function might have to be evaluated at compile time, declare it
constexpr - F.5: If a function is very small and time-critical, declare it
inline - F.6: If your function must not throw, declare it
noexcept - F.7: For general use, take
T*orT&arguments rather than smart pointers - F.8: Prefer pure functions
- F.9: Unused parameters should be unnamed
- F.10: If an operation can be reused, give it a name
- F.11: Use an unnamed lambda if you need a simple function object in one place only
- F.15: Prefer simple and conventional ways of passing information
- F.16: For “in” parameters, pass cheaply-copied types by value and others by reference to
const - F.17: For “in-out” parameters, pass by reference to non-
const - F.18: For “will-move-from” parameters, pass by
X&&andstd::movethe parameter - F.19: For “forward” parameters, pass by
TP&&and onlystd::forwardthe parameter - F.20: For “out” output values, prefer return values to output parameters
- F.21: To return multiple “out” values, prefer returning a struct
- F.60: Prefer
T*overT&when “no argument” is a valid option - F.22: Use
T*orowner<T*>to designate a single object - F.23: Use a
not_null<T>to indicate that “null” is not a valid value - F.24: Use a
span<T>or aspan_p<T>to designate a half-open sequence - F.25: Use a
zstringor anot_null<zstring>to designate a C-style string - F.26: Use a
unique_ptr<T>to transfer ownership where a pointer is needed - F.27: Use a
shared_ptr<T>to share ownership - F.42: Return a
T*to indicate a position (only) - F.43: Never (directly or indirectly) return a pointer or a reference to a local object
- F.44: Return a
T&when copy is undesirable and “returning no object” isn’t needed - F.45: Don’t return a
T&& - F.46:
intis the return type formain() - F.47: Return
T&from assignment operators - F.48: Don’t
return std::move(local) - F.49: Don’t return
const T - F.50: Use a lambda when a function won’t do (to capture local variables, or to write a local function)
- F.51: Where there is a choice, prefer default arguments over overloading
- F.52: Prefer capturing by reference in lambdas that will be used locally, including passed to algorithms
- F.53: Avoid capturing by reference in lambdas that will be used non-locally, including returned, stored on the heap, or passed to another thread
- F.54: When writing a lambda that captures
thisor any class data member, don’t use[=]default capture - F.55: Don’t use
va_argarguments - F.56: Avoid unnecessary condition nesting
C: Classes and class hierarchies
- C.1: Organize related data into structures (
structs orclasses) - C.2: Use
classif the class has an invariant; usestructif the data members can vary independently - C.3: Represent the distinction between an interface and an implementation using a class
- C.4: Make a function a member only if it needs direct access to the representation of a class
- C.5: Place helper functions in the same namespace as the class they support
- C.7: Don’t define a class or enum and declare a variable of its type in the same statement
- C.8: Use
classrather thanstructif any member is non-public - C.9: Minimize exposure of members
- C.10: Prefer concrete types over class hierarchies
- C.11: Make concrete types regular
- C.12: Don’t make data members
constor references in a copyable or movable type - C.13: If data member
Buses another data memberA, declareAbeforeB - C.20: If you can avoid defining default operations, do
- C.21: If you define or
=deleteany copy, move, or destructor function, define or=deletethem all - C.22: Make default operations consistent
- C.30: Define a destructor if a class needs an explicit action at object destruction
- C.31: All resources acquired by a class must be released by the class’s destructor
- C.32: If a class has a raw pointer (
T*) or reference (T&), consider whether it might be owning - C.33: If a class has an owning pointer member, define a destructor
- C.35: A base class destructor should be either public and virtual, or protected and non-virtual
- C.36: A destructor must not fail
- C.37: Make destructors
noexcept - C.40: Define a constructor if a class has an invariant
- C.41: A constructor should create a fully initialized object
- C.42: If a constructor cannot construct a valid object, throw an exception
- C.43: Ensure that a copyable class has a default constructor
- C.44: Prefer default constructors to be simple and non-throwing
- C.45: Don’t define a default constructor that only initializes data members; use default member initializers instead
- C.46: By default, declare single-argument constructors explicit
- C.47: Define and initialize data members in the order of member declaration
- C.48: Prefer default member initializers to member initializers in constructors for constant initializers
- C.49: Prefer initialization to assignment in constructors
- C.50: Use a factory function if you need “virtual behavior” during initialization
- C.51: Use delegating constructors to represent common actions for all constructors of a class
- C.52: Use inheriting constructors to import constructors into a derived class that does not need further explicit initialization
- C.60: Make copy assignment non-
virtual, take the parameter byconst&, and return by non-const& - C.61: A copy operation should copy
- C.62: Make copy assignment safe for self-assignment
- C.63: Make move assignment non-
virtual, take the parameter by&&, and return by non-const& - C.64: A move operation should move and leave its source in a valid state
- C.65: Make move assignment safe for self-assignment
- C.66: Make move operations
noexcept - C.67: A polymorphic class should suppress public copy/move
- C.80: Use
=defaultif you have to be explicit about using the default semantics - C.81: Use
=deletewhen you want to disable default behavior (without wanting an alternative) - C.82: Don’t call virtual functions in constructors and destructors
- C.83: For value-like types, consider providing a
noexceptswap function - C.84: A
swapfunction must not fail - C.85: Make
swapnoexcept - C.86: Make
==symmetric with respect to operand types andnoexcept - C.87: Beware of
==on base classes - C.89: Make a
hashnoexcept - C.90: Rely on constructors and assignment operators, not
memsetandmemcpy - C.100: Follow the STL when defining a container
- C.101: Give a container value semantics
- C.102: Give a container move operations
- C.103: Give a container an initializer list constructor
- C.104: Give a container a default constructor that sets it to empty
- C.109: If a resource handle has pointer semantics, provide
*and-> - C.120: Use class hierarchies to represent concepts with inherent hierarchical structure (only)
- C.121: If a base class is used as an interface, make it a pure abstract class
- C.122: Use abstract classes as interfaces when complete separation of interface and implementation is needed
- C.126: An abstract class typically doesn’t need a user-written constructor
- C.127: A class with a virtual function should have a virtual or protected destructor
- C.128: Virtual functions should specify exactly one of
virtual,override, orfinal - C.129: When designing a class hierarchy, distinguish between implementation inheritance and interface inheritance
- C.130: For making deep copies of polymorphic classes prefer a virtual
clonefunction instead of public copy construction/assignment - C.131: Avoid trivial getters and setters
- C.132: Don’t make a function
virtualwithout reason - C.133: Avoid
protecteddata - C.134: Ensure all non-
constdata members have the same access level - C.135: Use multiple inheritance to represent multiple distinct interfaces
- C.136: Use multiple inheritance to represent the union of implementation attributes
- C.137: Use
virtualbases to avoid overly general base classes - C.138: Create an overload set for a derived class and its bases with
using - C.139: Use
finalon classes sparingly - C.140: Do not provide different default arguments for a virtual function and an overrider
- C.145: Access polymorphic objects through pointers and references
- C.146: Use
dynamic_castwhere class hierarchy navigation is unavoidable - C.147: Use
dynamic_castto a reference type when failure to find the required class is considered an error - C.148: Use
dynamic_castto a pointer type when failure to find the required class is considered a valid alternative - C.149: Use
unique_ptrorshared_ptrto avoid forgetting todeleteobjects created usingnew - C.150: Use
make_unique()to construct objects owned byunique_ptrs - C.151: Use
make_shared()to construct objects owned byshared_ptrs - C.152: Never assign a pointer to an array of derived class objects to a pointer to its base
- C.153: Prefer virtual function to casting
- C.160: Define operators primarily to mimic conventional usage
- C.161: Use non-member functions for symmetric operators
- C.162: Overload operations that are roughly equivalent
- C.163: Overload only for operations that are roughly equivalent
- C.164: Avoid implicit conversion operators
- C.165: Use
usingfor customization points - C.166: Overload unary
&only as part of a system of smart pointers and references - C.167: Use an operator for an operation with its conventional meaning
- C.168: Define overloaded operators in the namespace of their operands
- C.170: If you feel like overloading a lambda, use a generic lambda
- C.180: Use
unions to save memory - C.181: Avoid “naked”
unions - C.182: Use anonymous
unions to implement tagged unions - C.183: Don’t use a
unionfor type punningEnum: Enumerations
- Enum.1: Prefer enumerations over macros
- Enum.2: Use enumerations to represent sets of related named constants
- Enum.3: Prefer class enums over “plain” enums
- Enum.4: Define operations on enumerations for safe and simple use
- Enum.5: Don’t use
ALL_CAPSfor enumerators - Enum.6: Avoid unnamed enumerations
- Enum.7: Specify the underlying type of an enumeration only when necessary
- Enum.8: Specify enumerator values only when necessary
R: Resource management
- R.1: Manage resources automatically using resource handles and RAII (Resource Acquisition Is Initialization)
- R.2: In interfaces, use raw pointers to denote individual objects (only)
- R.3: A raw pointer (a
T*) is non-owning - R.4: A raw reference (a
T&) is non-owning - R.5: Prefer scoped objects, don’t heap-allocate unnecessarily
- R.6: Avoid non-
constglobal variables - R.10: Avoid
malloc()andfree() - R.11: Avoid calling
newanddeleteexplicitly - R.12: Immediately give the result of an explicit resource allocation to a manager object
- R.13: Perform at most one explicit resource allocation in a single expression statement
- R.14: Avoid
[]parameters, preferspan - R.15: Always overload matched allocation/deallocation pairs
- R.20: Use
unique_ptrorshared_ptrto represent ownership - R.21: Prefer
unique_ptrovershared_ptrunless you need to share ownership - R.22: Use
make_shared()to makeshared_ptrs - R.23: Use
make_unique()to makeunique_ptrs - R.24: Use
std::weak_ptrto break cycles ofshared_ptrs - R.30: Take smart pointers as parameters only to explicitly express lifetime semantics
- R.31: If you have non-
stdsmart pointers, follow the basic pattern fromstd - R.32: Take a
unique_ptr<widget>parameter to express that a function assumes ownership of awidget - R.33: Take a
unique_ptr<widget>¶meter to express that a function reseats thewidget - R.34: Take a
shared_ptr<widget>parameter to express shared ownership - R.35: Take a
shared_ptr<widget>¶meter to express that a function might reseat the shared pointer - R.36: Take a
const shared_ptr<widget>¶meter to express that it might retain a reference count to the object ??? - R.37: Do not pass a pointer or reference obtained from an aliased smart pointer
ES: Expressions and statements
- ES.1: Prefer the standard library to other libraries and to “handcrafted code”
- ES.2: Prefer suitable abstractions to direct use of language features
- ES.3: Don’t repeat yourself, avoid redundant code
- ES.5: Keep scopes small
- ES.6: Declare names in for-statement initializers and conditions to limit scope
- ES.7: Keep common and local names short, and keep uncommon and non-local names longer
- ES.8: Avoid similar-looking names
- ES.9: Avoid
ALL_CAPSnames - ES.10: Declare one name (only) per declaration
- ES.11: Use
autoto avoid redundant repetition of type names - ES.12: Do not reuse names in nested scopes
- ES.20: Always initialize an object
- ES.21: Don’t introduce a variable (or constant) before you need to use it
- ES.22: Don’t declare a variable until you have a value to initialize it with
- ES.23: Prefer the
{}-initializer syntax - ES.24: Use a
unique_ptr<T>to hold pointers - ES.25: Declare an object
constorconstexprunless you want to modify its value later on - ES.26: Don’t use a variable for two unrelated purposes
- ES.27: Use
std::arrayorstack_arrayfor arrays on the stack - ES.28: Use lambdas for complex initialization, especially of
constvariables - ES.30: Don’t use macros for program text manipulation
- ES.31: Don’t use macros for constants or “functions”
- ES.32: Use
ALL_CAPSfor all macro names - ES.33: If you must use macros, give them unique names
- ES.34: Don’t define a (C-style) variadic function
- ES.40: Avoid complicated expressions
- ES.41: If in doubt about operator precedence, parenthesize
- ES.42: Keep use of pointers simple and straightforward
- ES.43: Avoid expressions with undefined order of evaluation
- ES.44: Don’t depend on order of evaluation of function arguments
- ES.45: Avoid “magic constants”; use symbolic constants
- ES.46: Avoid lossy (narrowing, truncating) arithmetic conversions
- ES.47: Use
nullptrrather than0orNULL - ES.48: Avoid casts
- ES.49: If you must use a cast, use a named cast
- ES.50: Don’t cast away
const - ES.55: Avoid the need for range checking
- ES.56: Write
std::move()only when you need to explicitly move an object to another scope - ES.60: Avoid
newanddeleteoutside resource management functions - ES.61: Delete arrays using
delete[]and non-arrays usingdelete - ES.62: Don’t compare pointers into different arrays
- ES.63: Don’t slice
- ES.64: Use the
T{e}notation for construction - ES.65: Don’t dereference an invalid pointer
- ES.70: Prefer a
switch-statement to anif-statement when there is a choice - ES.71: Prefer a range-
for-statement to afor-statement when there is a choice - ES.72: Prefer a
for-statement to awhile-statement when there is an obvious loop variable - ES.73: Prefer a
while-statement to afor-statement when there is no obvious loop variable - ES.74: Prefer to declare a loop variable in the initializer part of a
for-statement - ES.75: Avoid
do-statements - ES.76: Avoid
goto - ES.77: Minimize the use of
breakandcontinuein loops - ES.78: Don’t rely on implicit fallthrough in
switchstatements - ES.79: Use
defaultto handle common cases (only) - ES.84: Don’t try to declare a local variable with no name
- ES.85: Make empty statements visible
- ES.86: Avoid modifying loop control variables inside the body of raw for-loops
- ES.87: Don’t add redundant
==or!=to conditions - ES.100: Don’t mix signed and unsigned arithmetic
- ES.101: Use unsigned types for bit manipulation
- ES.102: Use signed types for arithmetic
- ES.103: Don’t overflow
- ES.104: Don’t underflow
- ES.105: Don’t divide by integer zero
- ES.106: Don’t try to avoid negative values by using
unsigned - ES.107: Don’t use
unsignedfor subscripts, prefergsl::indexPer: Performance
- Per.1: Don’t optimize without reason
- Per.2: Don’t optimize prematurely
- Per.3: Don’t optimize something that’s not performance critical
- Per.4: Don’t assume that complicated code is necessarily faster than simple code
- Per.5: Don’t assume that low-level code is necessarily faster than high-level code
- Per.6: Don’t make claims about performance without measurements
- Per.7: Design to enable optimization
- Per.10: Rely on the static type system
- Per.11: Move computation from run time to compile time
- Per.12: Eliminate redundant aliases
- Per.13: Eliminate redundant indirections
- Per.14: Minimize the number of allocations and deallocations
- Per.15: Do not allocate on a critical branch
- Per.16: Use compact data structures
- Per.17: Declare the most used member of a time-critical struct first
- Per.18: Space is time
- Per.19: Access memory predictably
- Per.30: Avoid context switches on the critical path
CP: Concurrency and parallelism
- CP.1: Assume that your code will run as part of a multi-threaded program
- CP.2: Avoid data races
- CP.3: Minimize explicit sharing of writable data
- CP.4: Think in terms of tasks, rather than threads
- CP.8: Don’t try to use
volatilefor synchronization - CP.9: Whenever feasible use tools to validate your concurrent code
- CP.20: Use RAII, never plain
lock()/unlock() - CP.21: Use
std::lock()orstd::scoped_lockto acquire multiplemutexes - CP.22: Never call unknown code while holding a lock (e.g., a callback)
- CP.23: Think of a joining
threadas a scoped container - CP.24: Think of a
threadas a global container - CP.25: Prefer
gsl::joining_threadoverstd::thread - CP.26: Don’t
detach()a thread - CP.31: Pass small amounts of data between threads by value, rather than by reference or pointer
- CP.32: To share ownership between unrelated
threads useshared_ptr - CP.40: Minimize context switching
- CP.41: Minimize thread creation and destruction
- CP.42: Don’t
waitwithout a condition - CP.43: Minimize time spent in a critical section
- CP.44: Remember to name your
lock_guards andunique_locks - CP.50: Define a
mutextogether with the data it guards. Usesynchronized_value<T>where possible - CP.51: Do not use capturing lambdas that are coroutines
- CP.52: Do not hold locks or other synchronization primitives across suspension points
- CP.53: Parameters to coroutines should not be passed by reference
- CP.60: Use a
futureto return a value from a concurrent task - CP.61: Use
async()to spawn concurrent tasks - CP.100: Don’t use lock-free programming unless you absolutely have to
- CP.101: Distrust your hardware/compiler combination
- CP.102: Carefully study the literature
- CP.110: Do not write your own double-checked locking for initialization
- CP.111: Use a conventional pattern if you really need double-checked locking
- CP.200: Use
volatileonly to talk to non-C++ memory - CP.201: ??? Signals
E: Error handling
- E.1: Develop an error-handling strategy early in a design
- E.2: Throw an exception to signal that a function can’t perform its assigned task
- E.3: Use exceptions for error handling only
- E.4: Design your error-handling strategy around invariants
- E.5: Let a constructor establish an invariant, and throw if it cannot
- E.6: Use RAII to prevent leaks
- E.7: State your preconditions
- E.8: State your postconditions
- E.12: Use
noexceptwhen exiting a function because of athrowis impossible or unacceptable - E.13: Never throw while being the direct owner of an object
- E.14: Use purpose-designed user-defined types as exceptions (not built-in types)
- E.15: Throw by value, catch exceptions from a hierarchy by reference
- E.16: Destructors, deallocation,
swap, and exception type copy/move construction must never fail - E.17: Don’t try to catch every exception in every function
- E.18: Minimize the use of explicit
try/catch - E.19: Use a
final_actionobject to express cleanup if no suitable resource handle is available - E.25: If you can’t throw exceptions, simulate RAII for resource management
- E.26: If you can’t throw exceptions, consider failing fast
- E.27: If you can’t throw exceptions, use error codes systematically
- E.28: Avoid error handling based on global state (e.g.
errno) - E.30: Don’t use exception specifications
- E.31: Properly order your
catch-clausesCon: Constants and immutability
- Con.1: By default, make objects immutable
- Con.2: By default, make member functions
const - Con.3: By default, pass pointers and references to
consts - Con.4: Use
constto define objects with values that do not change after construction - Con.5: Use
constexprfor values that can be computed at compile timeT: Templates and generic programming
- T.1: Use templates to raise the level of abstraction of code
- T.2: Use templates to express algorithms that apply to many argument types
- T.3: Use templates to express containers and ranges
- T.4: Use templates to express syntax tree manipulation
- T.5: Combine generic and OO techniques to amplify their strengths, not their costs
- T.10: Specify concepts for all template arguments
- T.11: Whenever possible use standard concepts
- T.12: Prefer concept names over
autofor local variables - T.13: Prefer the shorthand notation for simple, single-type argument concepts
- T.20: Avoid “concepts” without meaningful semantics
- T.21: Require a complete set of operations for a concept
- T.22: Specify axioms for concepts
- T.23: Differentiate a refined concept from its more general case by adding new use patterns.
- T.24: Use tag classes or traits to differentiate concepts that differ only in semantics.
- T.25: Avoid complementary constraints
- T.26: Prefer to define concepts in terms of use-patterns rather than simple syntax
- T.40: Use function objects to pass operations to algorithms
- T.41: Require only essential properties in a template’s concepts
- T.42: Use template aliases to simplify notation and hide implementation details
- T.43: Prefer
usingovertypedeffor defining aliases - T.44: Use function templates to deduce class template argument types (where feasible)
- T.46: (removed)
- T.47: Avoid highly visible unconstrained templates with common names
- T.48: If your compiler does not support concepts, fake them with
enable_if - T.49: Where possible, avoid type-erasure
- T.60: Minimize a template’s context dependencies
- T.61: Do not over-parameterize members (SCARY)
- T.62: Place non-dependent class template members in a non-templated base class
- T.64: Use specialization to provide alternative implementations of class templates
- T.65: Use tag dispatch to provide alternative implementations of a function
- T.67: Use specialization to provide alternative implementations for irregular types
- T.68: Use
{}rather than()within templates to avoid ambiguities - T.69: Inside a template, don’t make an unqualified non-member function call unless you intend it to be a customization point
- T.80: Do not naively templatize a class hierarchy
- T.81: Do not mix hierarchies and arrays
- T.82: Linearize a hierarchy when virtual functions are undesirable
- T.83: Do not declare a member function template virtual
- T.84: Use a non-template core implementation to provide an ABI-stable interface
- T.100: Use variadic templates when you need a function that takes a variable number of arguments of a variety of types
- T.101: ??? How to pass arguments to a variadic template ???
- T.102: How to process arguments to a variadic template
- T.103: Don’t use variadic templates for homogeneous argument lists
- T.120: Use template metaprogramming only when you really need to
- T.121: Use template metaprogramming primarily to emulate concepts
- T.122: Use templates (usually template aliases) to compute types at compile time
- T.123: Use
constexprfunctions to compute values at compile time - T.124: Prefer to use standard-library TMP facilities
- T.125: If you need to go beyond the standard-library TMP facilities, use an existing library
- T.140: If an operation can be reused, give it a name
- T.141: Use an unnamed lambda if you need a simple function object in one place only
- T.142?: Use template variables to simplify notation
- T.143: Don’t write unintentionally non-generic code
- T.144: Don’t specialize function templates
- T.150: Check that a class matches a concept using
static_assertCPL: C-style programming
- CPL.1: Prefer C++ to C
- CPL.2: If you must use C, use the common subset of C and C++, and compile the C code as C++
- CPL.3: If you must use C for interfaces, use C++ in the calling code using such interfaces
SF: Source files
- SF.1: Use a
.cppsuffix for code files and.hfor interface files if your project doesn’t already follow another convention - SF.2: A header file must not contain object definitions or non-inline function definitions
- SF.3: Use header files for all declarations used in multiple source files
- SF.4: Include header files before other declarations in a file
- SF.5: A
.cppfile must include the header file(s) that defines its interface - SF.6: Use
using namespacedirectives for transition, for foundation libraries (such asstd), or within a local scope (only) - SF.7: Don’t write
using namespaceat global scope in a header file - SF.8: Use
#includeguards for all header files - SF.9: Avoid cyclic dependencies among source files
- SF.10: Avoid dependencies on implicitly
#included names - SF.11: Header files should be self-contained
- SF.12: Prefer the quoted form of
#includefor files relative to the including file and the angle bracket form everywhere else - SF.13: Use portable header identifiers in
#includestatements - SF.20: Use
namespaces to express logical structure - SF.21: Don’t use an unnamed (anonymous) namespace in a header
- SF.22: Use an unnamed (anonymous) namespace for all internal/non-exported entities
SL: The Standard Library
- SL.1: Use libraries wherever possible
- SL.2: Prefer the standard library to other libraries
- SL.3: Do not add non-standard entities to namespace
std - SL.4: Use the standard library in a type-safe manner
- SL.con.1: Prefer using STL
arrayorvectorinstead of a C array - SL.con.2: Prefer using STL
vectorby default unless you have a reason to use a different container - SL.con.3: Avoid bounds errors
- SL.con.4: don’t use
memsetormemcpyfor arguments that are not trivially-copyable - SL.str.1: Use
std::stringto own character sequences - SL.str.2: Use
std::string_vieworgsl::span<char>to refer to character sequences - SL.str.3: Use
zstringorczstringto refer to a C-style, zero-terminated, sequence of characters - SL.str.4: Use
char*to refer to a single character - SL.str.5: Use
std::byteto refer to byte values that do not necessarily represent characters - SL.str.10: Use
std::stringwhen you need to perform locale-sensitive string operations - SL.str.11: Use
gsl::span<char>rather thanstd::string_viewwhen you need to mutate a string - SL.str.12: Use the
ssuffix for string literals meant to be standard-librarystrings - SL.io.1: Use character-level input only when you have to
- SL.io.2: When reading, always consider ill-formed input
- SL.io.3: Prefer
iostreams for I/O - SL.io.10: Unless you use
printf-family functions callios_base::sync_with_stdio(false) - SL.io.50: Avoid
endl - SL.C.1: Don’t use setjmp/longjmp
A: Architectural ideas
- A.1: Separate stable code from less stable code
- A.2: Express potentially reusable parts as a library
- A.4: There should be no cycles among libraries
NR: Non-Rules and myths
- NR.1: Don’t insist that all declarations should be at the top of a function
- NR.2: Don’t insist on having only a single
return-statement in a function - NR.3: Don’t avoid exceptions
- NR.4: Don’t insist on placing each class definition in its own source file
- NR.5: Don’t use two-phase initialization
- NR.6: Don’t place all cleanup actions at the end of a function and
goto exit - NR.7: Don’t make data members
protectedNL: Naming and layout suggestions
- NL.1: Don’t say in comments what can be clearly stated in code
- NL.2: State intent in comments
- NL.3: Keep comments crisp
- NL.4: Maintain a consistent indentation style
- NL.5: Avoid encoding type information in names
- NL.7: Make the length of a name roughly proportional to the length of its scope
- NL.8: Use a consistent naming style
- NL.9: Use
ALL_CAPSfor macro names only - NL.10: Prefer
underscore_stylenames - NL.11: Make literals readable
- NL.15: Use spaces sparingly
- NL.16: Use a conventional class member declaration order
- NL.17: Use K&R-derived layout
- NL.18: Use C++-style declarator layout
- NL.19: Avoid names that are easily misread
- NL.20: Don’t place two statements on the same line
- NL.21: Declare one name (only) per declaration
- NL.25: Don’t use
voidas an argument type - NL.26: Use conventional
constnotation - NL.27: Use a
.cppsuffix for code files and.hfor interface filesFAQ: Answers to frequently asked questions
- FAQ.1: What do these guidelines aim to achieve?
- FAQ.2: When and where was this work first announced?
- FAQ.3: Who are the authors and maintainers of these guidelines?
- FAQ.4: How can I contribute?
- FAQ.5: How can I become an editor/maintainer?
- FAQ.6: Have these guidelines been approved by the ISO C++ standards committee? Do they represent the consensus of the committee?
- FAQ.7: If these guidelines are not approved by the committee, why are they under
github.com/isocpp? - FAQ.8: Will there be a C++98 version of these Guidelines? A C++11 version?
- FAQ.9: Do these guidelines propose new language features?
- FAQ.10: What version of Markdown do these guidelines use?
- FAQ.50: What is the GSL (guidelines support library)?
- FAQ.51: Is github.com/Microsoft/GSL the GSL?
- FAQ.52: Why not supply an actual GSL implementation in/with these guidelines?
- FAQ.53: Why weren’t the GSL types proposed through Boost?
- FAQ.54: Has the GSL (guidelines support library) been approved by the ISO C++ standards committee?
- FAQ.55: If you’re using the standard types where available, why is the GSL
span<char>different from thestring_viewin the Library Fundamentals 1 Technical Specification and C++17 Working Paper? Why not just use the committee-approvedstring_view? - FAQ.56: Is
ownerthe same as the proposedobserver_ptr? - FAQ.57: Is
stack_arraythe same as the standardarray? - FAQ.58: Is
dyn_arraythe same asvectoror the proposeddynarray? - FAQ.59: Is
Expectsthe same asassert? - FAQ.60: Is
Ensuresthe same asassert?
安全配置中的编号条目
- Type.1: Avoid casts
- Type.2: Don’t use
static_castto downcast - Type.3: Don’t use
const_castto cast awayconst(i.e., at all) - Type.4: Don’t use C-style
(T)expressionor functionalT(expression)casts - Type.5: Don’t use a variable before it has been initialized
- Type.6: Always initialize a data member
- Type.7: Avoid naked union
- Type.8: Avoid varargs
- Bounds.1: Don’t use pointer arithmetic. Use
spaninstead - Bounds.2: Only index into arrays using constant expressions
- Bounds.3: No array-to-pointer decay
- Bounds.4: Don’t use standard-library functions and types that are not bounds-checked
- Lifetime.1: Don’t dereference a possibly invalid pointer
本站所有文章转发 CSDN 将按侵权追究法律责任,其它情况随意。