Google C++ スタイルガイド 日本語全訳

本ドキュメントは https://github.com/google/styleguide/ にて公開されているGoogle C++ Style Guideを日本語に訳したものです。
commit db0a263 on 18 Nov を底本としています。(訳文にマウスを重ねると原文が表示されます)
オリジナルと同様 CC-By 3.0 Licenseで頒布します。
誤訳の指摘・改善案は Issues or Pull Requestsまでお願いします。

C++ is one of the main development languages used by many of Google's open-source projects. C++は、多くのGoogleのオープンソースプロジェクトで使われている主要言語のうちのひとつです。 As every C++ programmer knows, the language has many powerful features, but this power brings with it complexity, which in turn can make code more bug-prone and harder to read and maintain. C++のプログラマなら誰でも知っているように、この言語はパワフルな機能がありますが、一方でこのパワフルさが複雑さを招き、バグを発生させやすくしたり、また可読性やメンテナンス性の妨げになったりしています。

The goal of this guide is to manage this complexity by describing in detail the dos and don'ts of writing C++ code. 本ガイドの目的は、C++のコードを書く際に、すべきこと、すべきでないことを詳しく説明することによって、この複雑性を管理下に置くことです。 These rules exist to keep the code base manageable while still allowing coders to use C++ language features productively. これらのルールは、プログラマがC++の言語機能を生産的に使用できるようにしたまま、コードベースを管理しやすくするために存在します。

Style, also known as readability, is what we call the conventions that govern our C++ code. スタイルとは、リーダビリティとしても知られ、私たちのC++コードを管理するための規約のことです。 The term Style is a bit of a misnomer, since these conventions cover far more than just source file formatting. これらの規約は、単にソースファイルのフォーマットだけではなく、広い範囲を含むためスタイルという用語はちょっとふさわしくないかもしれません。

Most open-source projects developed by Google conform to the requirements in this guide. Googleのオープンソースプロジェクトのほとんどが、本ガイドに則っています。

Note that this guide is not a C++ tutorial: we assume that the reader is familiar with the language. 注意してほしいのは、このガイドはC++のチュートリアルではないということです。このガイドは読者がC++に精通していることを想定して書かれています。

本ガイドの目的

Why do we have this document? なぜ本ガイドは書かれたか

There are a few core goals that we believe this guide should serve. このガイドで役立つと思われるいくつかの中核的目標があります。 These are the fundamental whys that underlie all of the individual rules. それらは、すべての個々のルールの根底となっている基本的なものです。 By bringing these ideas to the fore, we hope to ground discussions and make it clearer to our broader community why the rules are in place and why particular decisions have been made. 私たちは、この考え方を前面に出すことで、議論が行われ、より広範囲なコミュニティにおいて、これらのルールがなぜ作られ、なぜそのように決められたのか、より明確に伝わることを望んでいます。 If you understand what goals each rule is serving, it should be clearer to everyone when a rule may be waived (some can be), and what sort of argument or alternative would be necessary to change a rule in the guide. 個々のルールがどのような目的を果たそうとしているか理解できれば、いつルールの採用を取りやめるべきか、ルールを変更するためにどんな議論や代替案が必要か、より明確になるでしょう。

The goals of the style guide as we currently see them are as follows: 本スタイルガイドの目的は今のところ次のとおりです。

Style rules should pull their weight スタイルルールを重くしすぎないこと
The benefit of a style rule must be large enough to justify asking all of our engineers to remember it. 個々のスタイルルールは「所属するすべてのエンジニアが覚えなくてはならない」ことを正当化できるくらいに価値のあるものでなければなりません。 The benefit is measured relative to the codebase we would get without the rule, so a rule against a very harmful practice may still have a small benefit if people are unlikely to do it anyway. ルールの価値は「仮にそのルールが無かったら書かれたかもしれないコード」との比較で測定されます。このため、仮に「非常に有害な慣行に対するルール」があったとしても、「そもそもそんなルールがなくとも普通はしないよね」という場合、そのルールの価値は低いと考えます。 This principle mostly explains the rules we don’t have, rather than the rules we do: for example, goto contravenes many of the following principles, but is already vanishingly rare, so the Style Guide doesn’t discuss it. この原則は、どちらかというと、本スタイルガイドに書かれていないルールについて説明しています。例えば、gotoの濫用はこれに続く多くの原則に違反しますが、すでにそれが行われること自体がレアケースになっています。このため、本ガイドではgotoの濫用については取り扱いません。
Optimize for the reader, not the writer コードの(書き手ではなく)読み手に優しいこと
Our codebase (and most individual components submitted to it) is expected to continue for quite some time. 我々のコードベース(と、ほとんどの個々のコンポーネント)は、今後長い長い時を経ていくことが予想されます。 As a result, more time will be spent reading most of our code than writing it. 結果的に、そのコードを書くのに費やした時間に比べて、はるかに多くの時間がコードを読むために割かれることでしょう。 We explicitly choose to optimize for the experience of our average software engineer reading, maintaining, and debugging code in our codebase rather than ease when writing said code. 私たちは、私たちの平均的なエンジニアが「簡単にコードが書けること」よりも、「コードを読み、メンテし、デバッグがやりやすいこと」に最適化することを明示的に選択します。 "Leave a trace for the reader" is a particularly common sub-point of this principle: 特に「読者のためのヒントを残す」がこの原則の共通のサブテーマになっています。 When something surprising or unusual is happening in a snippet of code (for example, transfer of pointer ownership), leaving textual hints for the reader at the point of use is valuable (std::unique_ptr demonstrates the ownership transfer unambiguously at the call site). コードの中で見慣れないことをするとき(たとえばポインタの所有権を移す)、読み手のためにヒントを残しておくことは価値があります(std::unique_ptrは明白に所有権を移すことを示しています)。
Be consistent with existing code 既存のコードと一貫性が保たれていること
sing one style consistently through our codebase lets us focus on other (more important) issues. 1つのスタイルをコードベース全体で一貫して用いることで、私たちは他の(より重要な)問題にフォーカスすることができます。 Consistency also allows for automation: tools that format your code or adjust your #includes only work properly when your code is consistent with the expectations of the tooling. 一貫性は自動化を進めやすくもします。コードフォーマットツールは、ツールが期待するコードとあなたのコードが一貫しているときにのみ正しく動作します。 In many cases, rules that are attributed to "Be Consistent" boil down to "Just pick one and stop worrying about it"; 多くの場合「一貫性を保つ」に起因するルールは「ただ1つを選び、それについて悩むことをやめる」ということです。 the potential value of allowing flexibility on these points is outweighed by the cost of having people argue over them. これらの点の多様性を認めることの潜在的な価値よりも、それについて議論するコストの方が上回っているのです。
Be consistent with the broader C++ community when appropriate より広範囲なC++コミュニティと一貫性があること
Consistency with the way other organizations use C++ has value for the same reasons as consistency within our code base. C++を使う他の組織のやり方と一貫性を保つことも、我々コードベース内で一貫性を保つことと同じ理由で価値があります。 If a feature in the C++ standard solves a problem, or if some idiom is widely known and accepted, that's an argument for using it. あるC++標準の機能が問題を解けるのならば、あるイディオムが広く知られて受け入れられているのならば、それを使うための議論をします。 However, sometimes standard features and idioms are flawed, or were just designed without our codebase's needs in mind. しかし、時折、標準的な機能やイディオムは、不備があったり、あるいは単に私たちのコードベースのニーズを満たさない形でデザインされていたりします。 In those cases (as described below) it's appropriate to constrain or ban standard features. このような場合、これらの標準機能は制限または禁止することが適切です。 In some cases we prefer a homegrown or third-party library over a library defined in the C++ Standard, either out of perceived superiority or insufficient value to transition the codebase to the standard interface. いくつかのケースでは、C++標準ライブラリよりも自家製もしくはサードパーティのライブラリを選ぶ場合もあります。標準的なインターフェースにコードベースを移行することには知的優位性も十分な価値もありません。
Avoid surprising or dangerous constructs 見慣れない、あるいは危険な構成は避けること
C++ has features that are more surprising or dangerous than one might think at a glance. C++には、ちょっと考えただけでは気が付かないかもしれない、驚くような、あるいは危険な機能も存在します。 Some style guide restrictions are in place to prevent falling into these pitfalls. 本ガイドにおけるいくつかの制限ルールは、このような落とし穴を避けるためのものです。 There is a high bar for style guide waivers on such restrictions, because waiving such rules often directly risks compromising program correctness. これらのルールを破棄するとプログラムの正確性が失われる可能性があるため、それらのルールを破棄するためには高いハードルを設けています。
Avoid constructs that our average C++ programmer would find tricky or hard to maintain 平均的なC++プログラマがトリッキーと感じたり、メンテしにくいと感じたりするような構成は避けること
C++ has features that may not be generally appropriate because of the complexity they introduce to the code. C++はその複雑さゆえに、コードに導入するのが適切でないような機能も持っています。 In widely used code, it may be more acceptable to use trickier language constructs, because any benefits of more complex implementation are multiplied widely by usage, and the cost in understanding the complexity does not need to be paid again when working with new portions of the codebase. 広く使われているコードの中は、トリッキーな言語構造の方が受け入れられることもあるかもしれません。その場合の理由は、より複雑な実装が過去に繰り返されてきたことや、その複雑なものを理解するコストは、コードベースの新しい部分で仕事をする時にもう一度払う必要はないからです。 When in doubt, waivers to rules of this type can be sought by asking your project leads. これを疑うのであれば、このタイプのルールの破棄についてプロジェクトリーダーと相談してください。 This is specifically important for our codebase because code ownership and team membership changes over time: even if everyone that works with some piece of code currently understands it, such understanding is not guaranteed to hold a few years from now. これは我々のコードベースでは特に重要です。なぜなら、コードの担当者やチームメンバーは時とともに変わるからです。誰かがそのコードを理解して触っていたとしても、その理解が今から1年後にも保たれている保証はどこにもありません。
Be mindful of our scale 我々のプロジェクト規模に留意すること
With a codebase of 100+ million lines and thousands of engineers, some mistakes and simplifications for one engineer can become costly for many. 1億行以上のコードがあり、何千人ものエンジニアがいる状況において、ある一人のエンジニアのミスや単純化によるコストは非常に高くつくことがあります。 For instance it's particularly important to avoid polluting the global namespace: name collisions across a codebase of hundreds of millions of lines are difficult to work with and hard to avoid if everyone puts things into the global namespace. たとえば、グローバル名前空間汚染を避けることは非常に重要です。何億行ものコードベースの間で、もし、誰もがグローバル名前空間に何でもかんでもおいていたら、名前の衝突は不可避です。
Concede to optimization when necessary 必要な最適化は厭わない
Performance optimizations can sometimes be necessary and appropriate, even when they conflict with the other principles of this document. たとえ本ガイドのルールと競合したとしても、ときにパフォーマンスの最適化は必要かつ適切な場合もあります。

The intent of this document is to provide maximal guidance with reasonable restriction. 本文書の目的は理にかなった制限の下での最大限のガイダンスを提供することです。 As always, common sense and good taste should prevail. いつもどおり、常識や良識が優先されるべきです。 By this we specifically refer to the established conventions of the entire Google C++ community, not just your personal preferences or those of your team. これによって、我々は、具体的に、あなたの個人的な好みやあなたのチームについてだけではなく、Google C++コミュニティ全体で確立された規約に言及します。 Be skeptical about and reluctant to use clever or unusual constructs: the absence of a prohibition is not the same as a license to proceed. 巧妙なあるいは見慣れない構成には、懐疑的であってください。禁止されていないことはやっていいというわけではありません。 Use your judgment, and if you are unsure, please don't hesitate to ask your project leads to get additional input. 自分の判断に従ってください。ルールに賛同できない場合には、自プロジェクトのリーダーに対して更なるインプットを求めることを躊躇わないようにしください。

ヘッダファイル

In general, every .cc file should have an associated .h file. 原則的に、全ての.ccファイルは関連付く.hファイルを持つようにします。 There are some common exceptions, such as unittests and small .cc files containing just a main() function. ただし、ユニットテストやmain()だけを含むような小さな.ccは例外です。

Correct use of header files can make a huge difference to the readability, size and performance of your code. 正しくヘッダーファイルを扱うことは、コードの可読性やサイズ、パフォーマンスに大きな違いをもたらします。

The following rules will guide you through the various pitfalls of using header files. 以下のルールはヘッダーファイルに関する様々な落とし穴を避けて通るための道しるべとなるはずです。

自己完結型ヘッダー

Header files should be self-contained (compile on their own) and end in .h. ヘッダファイルは自己完結(単体でコンパイルできる)していなくてはならず、名前は.hで終わります。 Non-header files that are meant for inclusion should end in .inc and be used sparingly. ヘッダファイルではない、includeして使われるべきものは.incで終わるようにしますが、なるべく使用は控えるようにしましょう。

All header files should be self-contained. すべてのヘッダは自己完結していなくてはなりません。 Users and refactoring tools should not have to adhere to special conditions to include the header. ヘッダの使用者やリファクタリングツールは、そのヘッダがincludeされる際に、なんら特別な条件を守る必要がないようにします。 Specifically, a header should have header guards and include all other headers it needs. 特に、ヘッダにはインクルードガードを持たせ、そのヘッダ自身が必要とするすべての他のヘッダをincludeします。

Prefer placing the definitions for template and inline functions in the same file as their declarations. テンプレートやインライン関数などの定義は、宣言と同じファイルに含めましょう。 The definitions of these constructs must be included into every .cc file that uses them, or the program may fail to link in some build configurations. これらの定義は、それを用いるすべての.ccファイルに含まれる必要があり、さもなくばビルド環境によってはリンクに失敗するかもしれません。 If declarations and definitions are in different files, including the former should transitively include the latter. もし宣言と定義が違うファイルに分かれているならば、前者は後者をincludeすべきです。 Do not move these definitions to separately included header files (-inl.h); this practice was common in the past, but is no longer allowed. これらの定義を分割ヘッダファイル(-inl.h)に移動してはなりません。その手法は古いやり方であり、現在は禁止されています。

As an exception, a template that is explicitly instantiated for all relevant sets of template arguments, or that is a private implementation detail of a class, is allowed to be defined in the one and only .cc file that instantiates the template. 例外として、すべての関連するテンプレート引数セットについて明示的に例示されたテンプレートや、クラスのprivateな実装であるテンプレートは、そのテンプレートを実体化している唯一の.ccファイルで定義しても構いません。

There are rare cases where a file designed to be included is not self-contained. レアケースながら、includeされるが自己完結でないようなデザインも存在します。 These are typically intended to be included at unusual locations, such as the middle of another file. これらはたいていの場合、別のファイルの途中(中ほど)など変わった場所でinlucdeされることを想定しています。 They might not use header guards, and might not include their prerequisites. それらのファイルは、インクルードガードを持っていなかったり、そのヘッダ内で必要なものをincludeしていなかったりします。 Name such files with the .inc extension. このようなファイルには、.inc拡張子を持たせるようにします。 Use sparingly, and prefer self-contained headers when possible. また、なるべく使用は避け、可能な限り自己完結型ヘッダを使うことを選択しましょう。

インクルードガード

All header files should have #define guards to prevent multiple inclusion. すべてのヘッダファイルは、インクルードガード(#define guards)を持たなくてはなりません。 The format of the symbol name should be <PROJECT>_<PATH>_<FILE>_H_. その際のシンボル名は<PROJECT>_<PATH>_<FILE>_H_の形でなくてはなりません。

To guarantee uniqueness, they should be based on the full path in a project's source tree. ユニーク性を保証するため、プロジェクト内ソースツリーのフルパスに基づくものにします。 For example, the file foo/src/bar/baz.h in project foo should have the following guard: たとえば、プロジェクトfooに含まれるファイルfoo/src/bar/baz.hのガードは次のようにします。

#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_

...

#endif  // FOO_BAR_BAZ_H_

前方宣言

Avoid using forward declarations where possible. 前方宣言は可能な限り避けましょう。 Just #include the headers you need. 必要ならば単にヘッダを#includeしてください。

A "forward declaration" is a declaration of a class, function, or template without an associated definition. 前方宣言とは、関連付く定義のないクラス・関数・テンプレートの宣言のことです。

  • Forward declarations can save compile time, as #include force the compiler to open more files and process more input. 前方宣言は、#includeがコンパイラに多数のファイルを開かせてそれを処理させるためのコンパイル時間を節約することができます。
  • Forward declarations can save on unnecessary recompilation. 前方宣言は、不必要な再コンパイルを抑えることができます。 #include can force your code to be recompiled more often, due to unrelated changes in the header. #includeは、ヘッダの変更があなたのコードに無関係な場合でもコードを再コンパイルする必要があるため、再コンパイルの頻度が上がります。
  • Forward declarations can hide a dependency, allowing user code to skip necessary recompilation when headers change. 前方宣言は、依存性を隠してしまうため、コードの再コンパイルが必要な場合でも、それをスキップさせてしまうことがあります。
  • 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 otherwise-compatible changes to their APIs, such as widening a parameter type, adding a template parameter with a default value, or migrating to a new namespace. 関数やテンプレートの前方宣言は、元のヘッダの持ち主がAPIに対する互換性のない変更(パラメータの型を拡張したり、デフォルト値とともにテンプレートパラメータを増やしたり、新しい名前空間への移行したり)をすることを妨げになります。
  • Forward declaring symbols from namespace std:: yields undefined behavior. std::名前空間のシンボルに対する前方宣言は未定義動作を引き起こします。
  • It can be difficult to determine whether a forward declaration or a full #include is needed. 前方宣言だけで済むのか、#includeが必要かを判断するのは、難しいことがあります。 Replacing an #include with a forward declaration can silently change the meaning of code: 次のコードの#includeを単に前方宣言に置き換えてしまうと、コードの意味が変わってしまいます。
          // b.h:
          struct B {};
          struct D : B {};
    
          // good_user.cc:
          #include "b.h"
          void f(B*);
          void f(void*);
          void test(D* x) { f(x); }  // calls f(B*)
          
    If the #include was replaced with forward decls for B and D, test() would call f(void*). BDに対する#includeを、単に前方宣言に置き換えてしまった場合、test()は f(void*) を呼び出すことになるでしょう。
  • Forward declaring multiple symbols from a header can be more verbose than simply #includeing the header. ある1つのヘッダに含まれる複数のシンボルを前方宣言することは、単にそのヘッダを#includeするよりも冗長になってしまいます。
  • Structuring code to enable forward declaration (e.g. using pointer members instead of object members) can make the code slower and more complex. 前方宣言を使ってコードを作ろうとすると、(メンバにオブジェクトではなくポインタにしなくてはならないなど)、実行速度を下げ、しかも複雑なコードを書く羽目になるかもしれません。
  • Try to avoid forward declarations of entities defined in another project. 外部プロジェクト内に存在するモノの前方宣言は避けましょう。
  • When using a function declared in a header file, always #include that header. ヘッダで宣言されている関数を使いたい場合は、常にそのヘッダを#includeしましょう。
  • When using a class template, prefer to #include its header file. クラステンプレートを使いたい場合、ヘッダを#includeしましょう。

Please see Names and Order of Includes for rules about when to #include a header. ヘッダの#include関するルールインクルードの名前と順序も読んでください。

インライン関数

Define functions inline only when they are small, say, 10 lines or fewer. インライン関数は、関数の定義が小さいとき(10行以下)だけ使うようにしましょう。

You can declare functions in a way that allows the compiler to expand them inline rather than calling them through the usual function call mechanism. 関数は、コンパイラに対して、通常の関数呼び出しの代わりに、直接その場に展開することを許した形で宣言することができます。

Inlining a function can generate more efficient object code, as long as the inlined function is small. 関数のインライン化によって、インライン化される関数が小さければ、効率的なオブジェクトコードを生成することができるようになります。 Feel free to inline accessors and mutators, and other short, performance-critical functions. アクセサ(訳注:日本語圏でいうGetterのこと)やミューテータ(訳注:日本語圏でいうSetterのこと)、パフォーマンスクリティカルな小さい関数はどんどんインライン化しましょう。

Overuse of inlining can actually make programs slower. インライン関数を使いすぎると実のところプログラムは遅くなることもあります。 Depending on a function's size, inlining it can cause the code size to increase or decrease. 関数のサイズによっては、インライン化によってコードのサイズも増えたり減ったりします。 Inlining a very small accessor function will usually decrease code size while inlining a very large function can dramatically increase code size. とても小さいアクセッサ関数をインライン化する場合たいていコードのサイズは小さくなりますが、一方で、大きな関数をインライン化してしまうと全体のコードサイズは劇的に大きくなってしまうこともあります。 On modern processors smaller code usually runs faster due to better use of the instruction cache. イマドキのCPUにおいては、大抵の場合、命令キャッシュがうまく使える小さいコードの方が動作が速いです。

A decent rule of thumb is to not inline a function if it is more than 10 lines long. 経験的なルールとして、関数が10行より多くなったらインライン化すべきではないです。 Beware of destructors, which are often longer than they appear because of implicit member- and base-destructor calls! デストラクタに特に気を付けましょう。デストラクタは、暗黙的にメンバのデストラクタと基底デストラクタを呼び出すため見た目より長くなることがしばしばあるのです!

Another useful rule of thumb: it's typically not cost effective to inline functions with loops or switch statements (unless, in the common case, the loop or switch statement is never executed). もう1つ、有用な経験的なルールとして、大抵の場合、ループやswitch文のある関数は(それらがまったく実行されないような場合を除いて)インライン化しても効率的にはなりません。

It is important to know that functions are not always inlined even if they are declared as such; for example, virtual and recursive functions are not normally inlined. 重要な知識として、インライン関数はインラインで宣言されたからといって常にインライン化されるわけではありません。たとえば仮想関数や再帰関数は通常インライン化されません。 Usually recursive functions should not be inline. 通常、再帰関数はインライン化すべきではありません。 The main reason for making a virtual function inline is to place its definition in the class, either for convenience or to document its behavior, e.g., for accessors and mutators. 仮想関数をクラス内にインラインで定義する理由は、利便性や、(GetterやSetterの場合など)動作に関するドキュメントとしての役割があるからです。

インクルードの名前と順序

Use standard order for readability and to avoid hidden dependencies: 可読性を保つため、また、依存関係が隠れるのを防ぐため、次に示す順序でヘッダをincludeします。 Related header, C library, C++ library, other libraries' .h, your project's .h. 関連付くヘッダ, Cライブラリヘッダ, C++ライブラリヘッダ, 他のライブラリヘッダ, 自分のプロジェクトのヘッダ.

All of a project's header files should be listed as descendants of the project's source directory without use of UNIX directory shortcuts . (the current directory) or .. (the parent directory). プロジェクトヘッダはプロジェクトソースディレクトリ以下に配置しなくてはなりません。UNIXディレクトリショートカットである .(カレントディレクトリ)や、..(親ディレクトリ)は省きます。 For example, google-awesome-project/src/base/logging.h should be included as: たとえば、google-awesome-project/src/base/logging.hは次のようにインクルードされます。

#include "base/logging.h"

In dir/foo.cc or dir/foo_test.cc, whose main purpose is to implement or test the stuff in dir2/foo2.h, order your includes as follows: dir2/foo2.hの宣言を実装もしくはテストする目的のファイル、dir/foo.ccdir/foo_test.ccの中では、次の順序でincludeします。

  1. dir2/foo2.h.
  2. C system files. C システムヘッダ
  3. C++ system files. C++ システムヘッダ
  4. Other libraries' .h files. ほかのライブラリの.hファイル
  5. Your project's .h files. あなたのプロジェクトの.hファイル

With the preferred ordering, if dir2/foo2.h omits any necessary includes, the build of dir/foo.cc or dir/foo_test.cc will break. この順番であれば、もしdir2/foo2.hが必要なincludeを省くと、dir/foo.ccdir/foo_test.ccのビルドが失敗します。 Thus, this rule ensures that build breaks show up first for the people working on these files, not for innocent people in other packages. このルールであれば、ビルドが壊れたことを、他のパッケージで作業している無実の人ではなく、このファイルで作業をしていた人に一番最初に見せることができます。

dir/foo.cc and dir2/foo2.h are usually in the same directory (e.g. base/basictypes_test.cc and base/basictypes.h), but may sometimes be in different directories too. dir/foo.ccdir2/foo2.hは、一般的に同じディレクトリに置きますが(たとえば、base/basictypes_test.ccbase/basictypes.h)、異なるディレクトリに置いてもよいです。

Within each section the includes should be ordered alphabetically. 各セクション内ではアルファベット順に並べます。 Note that older code might not conform to this rule and should be fixed when convenient. 古いコードはこのルールに沿ってないかもしれませんが、利便性を考えたときは修正(訳注:be fixed)します。

You should include all the headers that define the symbols you rely upon, except in the unusual case of forward declaration . ヘッダは、前方宣言の例外を除いて、ヘッダが定義するシンボルに関連するすべてのヘッダをインクルードしなくてはなりません。 If you rely on symbols from bar.h, don't count on the fact that you included foo.h which (currently) includes bar.h: include bar.h yourself, unless foo.h explicitly demonstrates its intent to provide you the symbols of bar.h. もし、あなたがbar.hのシンボルに依存した定義をしようとしているのであれば、(仮にその時点でbar.hをインクルードしているfoo.hをインクルードしていたとしてもその事実は忘れて、)素直にbar.hをインクルードするようにします。foo.hbar.hのシンボルを提供すると明示的に説明している場合は除きます。 However, any includes present in the related header do not need to be included again in the related cc (i.e., foo.cc can rely on foo.h's includes). 関連ヘッダでインクルードしているヘッダは、ccファイルで再度インクルードしないようにします。(つまり、foo.ccは、foo.hがインクルードに依存することができます)

For example, the includes in google-awesome-project/src/foo/internal/fooserver.cc might look like this: 例をあげます。google-awesome-project/src/foo/internal/fooserver.ccのインクルードは次のようになります。

#include "foo/server/fooserver.h"

#include <sys/types.h>
#include <unistd.h>

#include <hash_map>
#include <vector>

#include "base/basictypes.h"
#include "base/commandlineflags.h"
#include "foo/server/bar.h"

Sometimes, system-specific code needs conditional includes. システム特有のコードは、しばしば条件が必要なインクルードを必要とする場合があります。 Such code can put conditional includes after other includes. このようなコードは他のインクルードの後に条件付きインクルードを配置します。 Of course, keep your system-specific code small and localized. もちろんのことですが、システム特有のコードは小さく局所的に保つようにしましょう。 Example: 例:

#include "foo/public/fooserver.h"

#include "base/port.h"  // For LANG_CXX11.

#ifdef LANG_CXX11
#include <initializer_list>
#endif  // LANG_CXX11

スコープ

名前空間

With few exceptions, place code in a namespace. 細かい例外を除いて、コードは名前空間の中に置いてください。 Namespaces should have unique names based on the project name, and possibly its path. 名前空間はプロジェクト名やファイルのパスに基づいてユニークな名前をつけてください。 Do not use using-directives (e.g. using namespace foo). また、usingディレクティブ(using namespace foo)は使ってはいけません。 Do not use inline namespaces. インライン名前空間も使ってはいけません。 For unnamed namespaces, see Unnamed Namespaces and Static Variables . 無名名前空間については無名名前空間と静的変数を参照してください。 .

Namespaces subdivide the global scope into distinct, named scopes, and so are useful for preventing name collisions in the global scope. 名前空間は、グローバルなスコープを名前付きのスコープに分割し、グローバルスコープにおける名前の衝突を防ぐのに有用です。

Namespaces provide a method for preventing name conflicts in large programs while allowing most code to use reasonably short names. 名前空間を用いることで、大きなプログラムにおける名前の衝突を避け、コードの大部分で理にかなった短い名前を使うことができるようになります。

For example, if two different projects have a class Foo in the global scope, these symbols may collide at compile time or at runtime. たとえば、2つのプロジェクトが同じ名前のクラスFooをグローバル名前空間に持っていたとすると、これらのシンボルはコンパイル時や実行時に衝突してしまうかもしれません。 If each project places their code in a namespace, project1::Foo and project2::Foo are now distinct symbols that do not collide, and code within each project's namespace can continue to refer to Foo without the prefix. しかし、各プロジェクトが独自の名前空間を持っていれば、同名だったシンボルproject1::Fooproject2::Fooは区別できるようになり、衝突しなくなります。一方で、各プロジェクトの名前空間内のコードは、引き続き、プレフィクスなしのFooで参照を保つことができます。

Inline namespaces automatically place their names in the enclosing scope. インライン名前空間は、自動的に、その内部に持つ名前を、自身を囲む(外側の)スコープに配置します。 Consider the following snippet, for example: 例として、次のスニペットについて考えます。

namespace X {
inline namespace Y {
  void foo();
}  // namespace Y
}  // namespace X

The expressions X::Y::foo() and X::foo() are interchangeable. このとき、式X::Y::foo()X::foo()とも書けます。 Inline namespaces are primarily intended for ABI compatibility across versions. インライン名前空間は、主にバージョン間におけるABIの互換性を保つことを目的としています。 `

Namespaces can be confusing, because they complicate the mechanics of figuring out what definition a name refers to. 名前空間は、その名前解決の仕組みの複雑さから、混乱を招くこともあります。

Inline namespaces, in particular, can be confusing because names aren't actually restricted to the namespace where they are declared. インライン名前空間は、事実上その中で宣言される名前を名前空間の中に閉じ込めないため、特に混乱しやすいです。 They are only useful as part of some larger versioning policy. インライン名前空間は、バージョン管理ポリシーの一部としてのみ役に立ちます。

In some contexts, it's necessary to repeatedly refer to symbols by their fully-qualified names. いくつかの文脈では、シンボルを解決するのに完全修飾された名前を用いる必要があります。 For deeply-nested namespaces, this can add a lot of clutter. 名前空間のネストが深い場合、コードが散らってしまうことになりかねません。

Namespaces should be used as follows: 名前空間は次のように使いましょう:

  • Follow the rules on Namespace Names 名前空間の名前のルールに従ってください。
  • Terminate namespaces with comments as shown in the given examples. 名前空間の終わりには、先の例の通り、コメントをつけてください。
  • Namespaces wrap the entire source file after includes, gflags definitions/declarations and forward declarations of classes from other namespaces. 名前空間は、include文やgflagsの定義と宣言、他の名前空間のクラスの前方宣言の後に続くソースコードをすべて包むようにしてください。

    // In the .h file
    namespace mynamespace {
    
    // All declarations are within the namespace scope.
    // Notice the lack of indentation.
    class MyClass {
     public:
      ...
      void Foo();
    };
    
    }  // namespace mynamespace
    
    // .h ファイル
    namespace mynamespace {
    
    // すべての宣言は名前空間のスコープに含めます。
    // インデントはしません。
    class MyClass {
     public:
      ...
      void Foo();
    };
    
    }  // namespace mynamespace
    
    // .ccファイル
    namespace mynamespace {
    
    // 関数の定義は名前空間に含めます。
    void MyClass::Foo() {
      ...
    }
    
    }  // namespace mynamespace
    

    More complex .cc files might have additional details, like flags or using-declarations. より複雑な .ccファイルは、flagsやusing宣言などを含む場合もあります。

    #include "a.h"
    
    DEFINE_FLAG(bool, someflag, false, "dummy flag");
    
    namespace a {
    
    using ::foo::bar;
    
    ...code for a...         // Code goes against the left margin.
    
    }  // namespace a
    
    #include "a.h"
    
    DEFINE_FLAG(bool, someflag, false, "dummy flag");
    
    namespace a {
    
    using ::foo::bar;
    
    ...code for a...         // コードの左側には余白を入れない。
    
    }  // namespace a
    
  • Do not declare anything in namespace std, including forward declarations of standard library classes. std名前空間の中には、標準ライブラリの前方宣言を含めて、何も宣言してはいけません。 Declaring entities in namespace std is undefined behavior, i.e., not portable. std名前空間の中に何かを宣言することは、コードの移植性を失わせ、未定義の動作を引き起こします。 To declare entities from the standard library, include the appropriate header file. 標準ライブラリのエンティティを宣言するためには適切なヘッダファイルをインクルードします。
  • You may not use a using-directive to make all names from a namespace available. 名前空間内のすべての名前を利用できるようにするためのusingディレクティブは使ってはいけません。

    // Forbidden -- This pollutes the namespace.
    using namespace foo;
    
    // ダメ。名前空間を汚染している。
    using namespace foo;
    
  • Do not use Namespace aliases at namespace scope in header files except in explicitly marked internal-only namespaces, because anything imported into a namespace in a header file becomes part of the public API exported by that file. 内部的に使用すると明示した名前空間の中を除いて、名前空間の別名(Namespace ailiases)をヘッダファイルの名前空間のスコープで使ってはいけません。なぜならば、ヘッダファイルで名前空間にインポートされたすべてのものが、そのヘッダファイルが提供するpublicなAPIの一部として公開されることになるからです。

    // Shorten access to some commonly used names in .cc files.
    namespace baz = ::foo::bar::baz;
    
    // .ccファイルの中でたくさん使われる名前へのショートカットを作る。
    namespace baz = ::foo::bar::baz;
    
    // Shorten access to some commonly used names (in a .h file).
    namespace librarian {
    namespace impl {  // Internal, not part of the API.
    namespace sidetable = ::pipeline_diagnostics::sidetable;
    }  // namespace impl
    
    inline void my_inline_function() {
      // namespace alias local to a function (or method).
      namespace baz = ::foo::bar::baz;
      ...
    }
    }  // namespace librarian
    
    // .hファイルの中で、よく使われる名前へのショートカットを作る。
    namespace librarian {
    namespace impl {  // 内部用。APIではありません。
    namespace sidetable = ::pipeline_diagnostics::sidetable;
    }  // namespace impl
    
    inline void my_inline_function() {
      // 関数内に限定された名前空間の別名。
      namespace baz = ::foo::bar::baz;
      ...
    }
    }  // namespace librarian
    
  • Do not use inline namespaces.インライン名前空間は使ってはいけません。

無名名前空間と静的変数

When definitions in a .cc file do not need to be referenced outside that file, place them in an unnamed namespace or declare them static. .ccファイル中に、ファイル外から参照される必要がない定義を行うときは、それらを無名の名前空間内で宣言するか、staticに宣言します。 Do not use either of these constructs in .h files. これらの宣言を.hにおいてはいけません。

All declarations can be given internal linkage by placing them in unnamed namespaces, and functions and variables can be given internal linkage by declaring them static. 無名名前空間内のすべての宣言は内部リンケージとなります。またstaticに宣言された関数や変数も内部リンケージとなります。 This means that anything you're declaring can't be accessed from another file. 内部リンケージとなったものは、他のファイルからアクセスできません。 If a different file declares something with the same name, then the two entities are completely independent. 仮に、他のファイルで同じ名前が宣言されていたとしても、それらは2つの独立した別々の実体として扱われます。

Use of internal linkage in .cc files is encouraged for all code that does not need to be referenced elsewhere. .ccで内部リンケージを使うことで、他の場所からこれらのコードは参照されてないということを強調できます。 Do not use internal linkage in .h files. .hファイルでは内部リンケージは使用してはいけません。

Format unnamed namespaces like named namespaces. 無名名前空間も、名前付きの名前空間と同じようにフォーマットします。 In the terminating comment, leave the namespace name empty: 無名名前空間が終わるときのコメントは、以下の例のように名前空間名を空白のままにしておきます。

namespace {
...
}  // namespace

メンバではない関数、静的メンバ関数、グローバル関数

Prefer placing nonmember functions in a namespace; use completely global functions rarely. メンバではない関数はいずれかの名前空間内におきましょう。完全なグローバル関数は滅多に使ってはいけません。 Prefer grouping functions with a namespace instead of using a class as if it were a namespace. グローバル関数をグループ化するときは、クラスではなく名前空間を使いましょう。 Static methods of a class should generally be closely related to instances of the class or the class's static data. 静的メンバ関数は、そのクラスのインスタンスや静的メンバ変数と関連性が強い場合にのみ用います。

Nonmember and static member functions can be useful in some situations. 静的メンバ関数や、メンバではない通常の関数は、いくつかのシチュエーションで有用です。 Putting nonmember functions in a namespace avoids polluting the global namespace. 通常の関数はいずれかの名前空間内に置くことで、グローバル名前空間の汚染を避けられます。

Nonmember and static member functions may make more sense as members of a new class, especially if they access external resources or have significant dependencies. 通常の関数や、静的メンバ関数は、それらが外部のリソースにアクセスしたり強く依存したりしているときに、クラスのメンバとするよりも理にかなっている場合があります。

Sometimes it is useful to define a function not bound to a class instance. 場合により、関数はクラスインスタンスに紐付けない方が便利なことがあります。 Such a function can be either a static member or a nonmember function. このような関数は、静的メンバ関数やメンバではない通常の関数とすることができます。 Nonmember functions should not depend on external variables, and should nearly always exist in a namespace. メンバでない関数は、外部の変数に依存してはいけません。 また、常に近しい名前空間の中に存在していなければなりません。 Rather than creating classes only to group static member functions which do not share static data, use namespaces instead. 静的な変数を共有しない、通常の関数をまとめるだけのクラスを作るのではなく、名前空間を使います。 For a header myproject/foo_bar.h, for example, write 例として、myproject/foo_bar.hは以下のように記述します。

namespace myproject {
namespace foo_bar {
void Function1();
void Function2();
}  // namespace foo_bar
}  // namespace myproject

instead of 悪い例:

namespace myproject {
class FooBar {
 public:
  static void Function1();
  static void Function2();
};
}  // namespace myproject

If you define a nonmember function and it is only needed in its .cc file, use internal linkage to limit its scope. 通常の関数が特定の.ccファイルでのみ使用される場合、内部リンケージを用いることで、スコープを制限することができます。

ローカル変数

Place a function's variables in the narrowest scope possible, and initialize variables in the declaration. 関数内の変数は、可能な限りそのスコープを狭めるようにしてください。また、関数内の変数は、宣言と同時に初期化してください。

C++ allows you to declare variables anywhere in a function. C++では、関数のどこでも変数を宣言することができます。 We encourage you to declare them in as local a scope as possible, and as close to the first use as possible. 我々は、変数のスコープをできる限り局所的にし、できる限り初めて使用する場所の近くで宣言することをおすすめしています。 This makes it easier for the reader to find the declaration and see what type the variable is and what it was initialized to. そうすることによって、コードの読者が、変数の宣言がどこにあるか、型は何か、どのように初期化されたかを、見つけやすくすることができます。 In particular, initialization should be used instead of declaration and assignment, e.g.: 特に、変数の初期化は宣言と同時に行うようにし、宣言と代入を別に行うようなことは避けてください。例:

int i;
i = f();      // Bad -- initialization separate from declaration.
int i;
i = f();      // 悪い例。初期化が宣言と分かれている。
int j = g();  // Good -- declaration has initialization.
int j = g();  // よい例。宣言と同時に初期化が行われている。
std::vector<int> v;
v.push_back(1);  // Prefer initializing using brace initialization.
v.push_back(2);
std::vector<int> v;
v.push_back(1);  // {}による初期化を使う方がよい。
v.push_back(2);
std::vector<int> v = {1, 2};  // Good -- v starts initialized.
std::vector<int> v = {1, 2};  // よい例。 vは初期化されている。

Variables needed for if, while and for statements should normally be declared within those statements, so that such variables are confined to those scopes. E.g.: if文やwhile文、for文で使用される変数は、通常は、それらの文の中で宣言します。そうすることで、変数のスコープを制限することができます。例:

while (const char* p = strchr(str, '/')) str = p + 1;

There is one caveat: if the variable is an object, its constructor is invoked every time it enters scope and is created, and its destructor is invoked every time it goes out of scope. ただし、もし変数がオブジェクトだったとすると、スコープに入るたびに毎回コンストラクタが呼ばれ、オブジェクトが生成され、スコープから出るたびに毎回デストラクタが呼ばれることになります。

// Inefficient implementation:
for (int i = 0; i < 1000000; ++i) {
  Foo f;  // My ctor and dtor get called 1000000 times each.
  f.DoSomething(i);
}
// 非効率的な実装
for (int i = 0; i < 1000000; ++i) {
  Foo f;  // コンストラクタとデストラクタがそれぞれ 1000000 回ずつ呼ばれる。
  f.DoSomething(i);
}

It may be more efficient to declare such a variable used in a loop outside that loop: こういった場合、変数はループの外で宣言する方が効率的になる場合があります。

Foo f;  // My ctor and dtor get called once each.
for (int i = 0; i < 1000000; ++i) {
  f.DoSomething(i);
}
Foo f;  // コンストラクタとデストラクタは1回ずつ呼ばれる。
for (int i = 0; i < 1000000; ++i) {
  f.DoSomething(i);
}

静的変数とグローバル変数

Variables of class type with static storage duration are forbidden: they cause hard-to-find bugs due to indeterminate order of construction and destruction. 静的記憶域期間(static storage duration)を持ったクラス型の変数は禁止です。これらの変数は不定な順番で生成(construct)・破壊(destruct)されるため、発見が困難な不具合を引き起こすことにつながります。 However, such variables are allowed if they are constexpr: they have no dynamic initialization or destruction. ただし、そのような変数でもconstexprと共に定義される場合は使用が認められます。これらは動的な初期化や破壊が行われないため問題になりません。

Objects with static storage duration, including global variables, static variables, static class member variables, and function static variables, must be Plain Old Data (POD): only ints, chars, floats, or pointers, or arrays/structs of POD. 静的な生存時間を持つオブジェクト(グローバル変数や静的変数、静的クラスメンバ変数、関数内静的変数を含む)は、必ずPlain Old Data(POD)でなくてはなりません。PODとは、組み込みの整数型(int,char,...)、浮動小数点型(float,double,...)、ポインタ、PODの配列、PODだけで構成された構造体のことです。

The order in which class constructors and initializers for static variables are called is only partially specified in C++ and can even change from build to build, which can cause bugs that are difficult to find. C++において、静的変数のコンストラクタや初期化子の呼び出し順序は、部分的にしか決められておらず、ビルドのたびに変わる可能性すらあり、これらは非常に見つけづらいバグの元となります。 Therefore in addition to banning globals of class type, we do not allow non-local static variables to be initialized with the result of a function, unless that function (such as getenv(), or getpid()) does not itself depend on any other globals. このため、クラス型のグローバル変数に加え、(呼び出す関数が他のグローバルに依存していない場合を除いて)関数の結果によって初期化されるローカルでない静的変数も許容できません。 However, a static POD variable within function scope may be initialized with the result of a function, since its initialization order is well-defined and does not occur until control passes through its declaration. 一方で、関数スコープの静的POD変数は、その初期化順序は十分に定義され、かつ、その宣言を初めて通過するまで初期化されないため、関数の結果で初期化されても問題ありません。

Likewise, global and static variables are destroyed when the program terminates, regardless of whether the termination is by returning from main() or by calling exit(). ここまでの初期化の話と同様に、グローバル変数や静的変数は、(main()の処理が終わったかexit()の呼び出しであるかに関わらず)プログラムの終了時に破壊されます。 The order in which destructors are called is defined to be the reverse of the order in which the constructors were called. このときのデストラクタが呼ばれる順序は、コンストラクタが呼ばれた順の逆順と定義されていますが、 Since constructor order is indeterminate, so is destructor order. そもそも、コンストラクタの呼び出し順序は決まっていないため、デストラクタの呼び出し順序も決まっていません。 For example, at program-end time a static variable might have been destroyed, but code still running — perhaps in another thread — tries to access it and fails. たとえば、プログラム終了処理時には静的変数は破壊されますが、まだ実行中のコード(おそらく別スレッド)がその変数にアクセスしようとして失敗するかもしれません。 Or the destructor for a static string variable might be run prior to the destructor for another variable that contains a reference to that string. あるいは、静的なstringのデストラクタが、その文字列への参照を持つ別の変数のデストラクタよりも先に実行されてしまうかもしれません。

One way to alleviate the destructor problem is to terminate the program by calling quick_exit() instead of exit(). このデストラクタ問題を軽減する1つの方法は、プログラムを終了するためにexit()ではなくquick_exit()を呼び出すことです。 The difference is that quick_exit() does not invoke destructors and does not invoke any handlers that were registered by calling atexit(). quick_exit()は、exit()と違って、変数のデストラクタを呼び出さず、atexit()で事前に登録されたハンドラも呼び出しません。 If you have a handler that needs to run when a program terminates via quick_exit() (flushing logs, for example), you can register it using at_quick_exit(). たとえばログのflushなど、quick_exit()でプログラムを終了する場合に実行しないといけないことがある場合はat_quick_exit()で、ハンドラを登録することができます。 (If you have a handler that needs to run at both exit() and quick_exit(), you need to register it in both places.) (exit()quick_exit()のどちらが呼び出されてもハンドラを実行したい場合は、両方に登録しておく必要があります。)

As a result we only allow static variables to contain POD data. 結果的には、静的変数に格納できるものはPODだけです。 This rule completely disallows std::vector (use C arrays instead), or string (use const char []). このルールは、静的なstd::vectorstringを認めないことを意味します。 これらの代わりに、Cの配列や、const char[]を使うようにしてください。

If you need a static or global variable of a class type, consider initializing a pointer (which will never be freed), from either your main() function or from pthread_once(). もし、クラス型の静的変数やグローバル変数がほしくなった場合は、変数をポインタとして用意し、main()pthread_once()の処理の中などで初期化する方法を検討してください(ポインタの解放処理はどこにも書きません) 。 Note that this must be a raw pointer, not a "smart" pointer, since the smart pointer's destructor will have the order-of-destructor issue that we are trying to avoid. このとき宣言するポインタは生のポインタとし、スマートポインタ等を使用してはいけません。 スマートポインタのデストラクタは、ここまで回避しようとしてきたデストラクタ呼び出し順序の問題を再燃させてしまいます。

クラス

Classes are the fundamental unit of code in C++. クラスはC++におけるコードの基本単位です。 Naturally, we use them extensively. もちろん、我々は、それらを広く使っています。 This section lists the main dos and don'ts you should follow when writing a class. このセクションでは、クラスを書くときに、すべきこと、すべきでないことについて述べます。

コンストラクタで行うこと

Avoid virtual method calls in constructors, and avoid initialization that can fail if you can't signal an error. コンストラクタで仮想メンバ関数を呼ぶのはやめましょう。エラーを伝える手段がない場合、失敗するかもしれない初期化処理を行うのはやめましょう。

It is possible to perform arbitrary initialization in the body of the constructor. コンストラクタでは任意の初期化処理を行うことができます。

  • No need to worry about whether the class has been initialized or not. クラスが初期化済みであるかどうか、気にかけなくてよくなります。
  • Objects that are fully initialized by constructor call can be const and may also be easier to use with standard containers or algorithms. コンストラクタで完全に初期化されるオブジェクトは、constにしやすく、標準コンテナや標準アルゴリズムで扱いやすくなります。
  • If the work calls virtual functions, these calls will not get dispatched to the subclass implementations. コンストラクタで仮想関数が呼び出されたとしても、それらは派生クラスの実装を呼び出しません。 Future modification to your class can quietly introduce this problem even if your class is not currently subclassed, causing much confusion. 現時点で派生クラスがなくとも、将来的にクラスが変更された場合に、地味にこの問題を引き起こし、混乱を招くかもしれません。
  • There is no easy way for constructors to signal errors, short of crashing the program (not always appropriate) or using exceptions (which are forbidden). コンストラクタには、簡単にエラーを伝える方法がありません。せいぜい、プログラムをクラッシュさせる(常にそれが適切とは限らない)方法や、例外を使う(ルール上禁止)方法くらいです。
  • If the work fails, we now have an object whose initialization code failed, so it may be an unusual state requiring a bool IsValid() state checking mechanism (or similar) which is easy to forget to call. コンストラクタの処理が失敗した場合、初期化に失敗したオブジェクトができてしまいます。bool IsValid()のような状態をチェックする仕組みを用意しても、その呼び出しは簡単に忘れられてしまいます。
  • You cannot take the address of a constructor, so whatever work is done in the constructor cannot easily be handed off to, for example, another thread. コンストラクタのアドレスを得ることはできません。このため、コンストラクタで行われる処理の内容を他のスレッドに渡したりするようなことは、簡単にはできません。

Constructors should never call virtual functions. コンストラクタでは仮想関数を呼び出してはいけません。 If appropriate for your code , terminating the program may be an appropriate error handling response. それが適切と考えるのであれば、プログラムを強制終了するのもエラー処理の1つのやり方です。 Otherwise, consider a factory function or Init() method. さもなくば、ファクトリ関数やInit()メソッドの導入を検討しましょう。 Avoid Init() methods on objects with no other states that affect which public methods may be called (semi-constructed objects of this form are particularly hard to work with correctly). どのpublicメソッドが呼びだされてもよいかという他の状態を持たないオブジェクトのInit()メソッドは避けてください(特に、中途半端に生成されたオブジェクトを正しく動作させるのは困難です)。

暗黙的型変換

Do not define implicit conversions. 暗黙的型変換を新たに定義してはいけません。 Use the explicit keyword for conversion operators and single-argument constructors. 型変換演算子や、1つの引数をとるコンストラクタにおいてはexplicitキーワードを使用してください。

Implicit conversions allow an object of one type (called the source type) to be used where a different type (called the destination type ) is expected, such as when passing an int argument to a function that takes a double parameter. 暗黙的型変換によって、ある型のオブジェクトを異なる型のオブジェクトとして扱えるようになります。たとえば、double型の仮引数をとる関数にint型の値を渡せます。

In addition to the implicit conversions defined by the language, users can define their own, by adding appropriate members to the class definition of the source or destination type. 言語で元々定義されている暗黙的型変換に加えて、変換元の型か変換先の型のクラス定義に適切なメンバを加えることで、新たに暗黙的型変換を定義することができます。 An implicit conversion in the source type is defined by a type conversion operator named after the destination type (e.g. operator bool() ). 変換元の型における暗黙的型変換は、変換先型の名前をつけた型変換演算子によって定義されます(例:operator bool())。 An implicit conversion in the destination type is defined by a constructor that can take the source type as its only argument (or only argument with no default value). 変換先の型における暗黙的型変換は、変換元の型の引数を1つだけとる(またはデフォルト値のない引数を1つだけとる)コンストラクタによって定義されます。

The explicit keyword can be applied to a constructor or (since C++11) a conversion operator, to ensure that it can only be used when the destination type is explicit at the point of use, e.g. with a cast. explicitキーワードは、コンストラクタや(C++11では)型変換演算子につけることができます。これによって、型変換を、変換先の型が明示された場合にのみ行うよう限定することができます。 This applies not only to implicit conversions, but to C++11's list initialization syntax: これは、暗黙的型変換だけではなく、以下に示すようなC++11のリスト初期化構文にも適用されます。

class Foo {
  explicit Foo(int x, double y);
  ...
};

void Func(Foo f);
Func({42, 3.14});  // Error
This kind of code isn't technically an implicit conversion, but the language treats it as one as far as explicit is concerned. このようなコードは何らテクニカルな暗黙的型変換はしていませんが、言語上explicitに関連していると見なして扱われます。
  • Implicit conversions can make a type more usable and expressive by eliminating the need to explicitly name a type when it's obvious. 暗黙的型変換は、型の利便性を高め、型が明確であるときには型の名前を省略可能であるため表現上も優れています。
  • Implicit conversions can be a simpler alternative to overloading. 暗黙的型変換は単にオーバーロードの代替手段としても利用可能です。
  • List initialization syntax is a concise and expressive way of initializing objects. リスト初期化子による構文は、簡潔で表現的に優れたオブジェクトの初期化方法です。
  • Implicit conversions can hide type-mismatch bugs, where the destination type does not match the user's expectation, or the user is unaware that any conversion will take place. 暗黙的型変換は、型の不一致によるバグを隠してしまうことがあります。たとえば、変換先の型がユーザの期待どおりにならなかったり、そもそもその場で型変換が行わることに気づかなかったりします。
  • Implicit conversions can make code harder to read, particularly in the presence of overloading, by making it less obvious what code is actually getting called. 暗黙的型変換は、コードの可読性を下げる場合があります。特に、関数にオーバーロードが存在する場合、どれが実際に呼び出されるのかをわかりにくくしてしまうことがあります。
  • Constructors that take a single argument may accidentally be usable as implicit type conversions, even if they are not intended to do so. 1つの引数をとるコンストラクタが、意図せず型変換のために呼び出されてしまうことがあります。
  • When a single-argument constructor is not marked explicit, there's no reliable way to tell whether it's intended to define an implicit conversion, or the author simply forgot to mark it. 1つの引数をとるコンストラクタがexplicitでマークされていなかったとき、それが意図した暗黙的型変換のために書かれているのか、単にコードの著者がexplicitをつけるのを忘れてしまっただけなのか、信頼できる判断方法がありません。
  • It's not always clear which type should provide the conversion, and if they both do, the code becomes ambiguous. 変換元の型と変換先の型との、どちらの型が型変換を提供すべきかが常に明確であるとは限りません。もし両方がも型変換機能を持っていた場合、コードが曖昧になってしまいます。
  • List initialization can suffer from the same problems if the destination type is implicit, particularly if the list has only a single element. リスト初期化子は、変換先の型が暗黙的型変換を持つとき同じ問題にぶつかります(特にリストに1要素しか持っていなかった場合)。

Type conversion operators, and constructors that are callable with a single argument, must be marked explicit in the class definition. 型変換演算子と1つの引数で呼び出せるコンストラクタはexplicitでマークされていなくてはなりません。 As an exception, copy and move constructors should not be explicit, since they do not perform type conversion. 例外として、コピーコンストラクタとムーブコンストラクタはexplicitでマークされているべきではありません。これらは型変換を行うものではないからです。 Implicit conversions can sometimes be necessary and appropriate for types that are designed to transparently wrap other types. また、ある型が他の型を透過的にラップするようデザインされている場合など、暗黙的型変換が必要かつ適切な時もあります。 In that case, contact your project leads to request a waiver of this rule. そのような場合においては、プロジェクトリーダーと相談し、このルールの適用から外してください。

Constructors that cannot be called with a single argument should usually omit explicit. 通常、1つの引数では呼び出せないコンストラクタについてはexplicitを省略します。 Constructors that take a single std::initializer_list parameter should also omit explicit, in order to support copy-initialization (e.g. MyType m = {1, 2};). また、1つのstd::initializer_list型の引数をとるコンストラクタについも、コピーによる初期化(例: MyType m = {1, 2};)をサポートするためにexplicitを省略してください。

コピー可能な型・ムーブ可能な型

Support copying and/or moving if these operations are clear and meaningful for your type. コピーやムーブは、それの実装が明確でかつ意味のある場合に限って実装してください。 Otherwise, disable the implicitly generated special functions that perform copies and moves. それ以外の場合には、暗黙的に自動生成されるコピー・ムーブ関数は無効にしてください。

A copyable type allows its objects to be initialized or assigned from any other object of the same type, without changing the value of the source. 型をコピー可能にすることによって、他の同じ型のオブジェクトから、元となるオブジェクトを変更することなく、自分自身の初期化や自分自身への代入ができるようになります。 For user-defined types, the copy behavior is defined by the copy constructor and the copy-assignment operator. ユーザ定義の型においては、コピーの挙動は、コピーコンストラクタやコピー代入演算子によって定義されます。 string is an example of a copyable type. コピー可能な型の一例としてstringがあります。

A movable type is one that can be initialized and assigned from temporaries (all copyable types are therefore movable). ムーブ可能な型は、一時オブジェクトからの初期化または代入が可能な型です(ゆえに、コピー可能な型は常にムーブ可能な型です)。 std::unique_ptr<int> is an example of a movable but not copyable type. ムーブは可能ですがコピーは不可能な型の一例としてstd::unique_ptr<int>があります。 For user-defined types, the move behavior is defined by the move constructor and the move-assignment operator. ユーザ定義の型においては、ムーブの挙動は、ムーブコンストラクタやムーブ代入演算子によって定義されます。

The copy/move constructors can be implicitly invoked by the compiler in some situations, e.g. when passing objects by value. コピーコンストラクタやムーブコンストラクタは、オブジェクトの値渡しなどの際、コンパイラによって暗黙的に呼び出されます。

Objects of copyable and movable types can be passed and returned by value, which makes APIs simpler, safer, and more general. コピー可能・ムーブ可能なオブジェクトは、値渡し・値戻しができるため、APIがシンプルかつ安全で、より一般的な形になります。 Unlike when passing objects by pointer or reference, there's no risk of confusion over ownership, lifetime, mutability, and similar issues, and no need to specify them in the contract. この場合は、オブジェクトのポインタ渡し・参照渡しと違って、オブジェクトの所有権や生存時間、ミュータビリティなどに関する危険がなく、それらに関する前提条件も必要なくなります。 It also prevents non-local interactions between the client and the implementation, which makes them easier to understand, maintain, and optimize by the compiler. また、呼び出し元と実装をつないでしまうような局所的でない相互作用も自動的に防がれます。これによって、理解しやすく、メンテナンスしやすく、コンパイラによって最適化が掛かりやすくなります。 Further, such objects can be used with generic APIs that require pass-by-value, such as most containers, and they allow for additional flexibility in e.g., type composition. さらに、このようなオブジェクトは、多くのコンテナ型のような値渡しを要求するAPIに利用することができる他、型の合成などにおいて柔軟な扱い方ができるようにもなります。

Copy/move constructors and assignment operators are usually easier to define correctly than alternatives like Clone(), CopyFrom() or Swap(), because they can be generated by the compiler, either implicitly or with = default. コピー・ムーブを行うコンストラクタや代入演算子は、一般に、Clone(), CopyFrom()あるいはSwap()といった代替的な方法に比べて、正しく定義することが容易です。なぜならば、これらのコンストラクタや代入演算子は暗黙的に、または明示的に= defaultと記載することで、コンパイラに生成させることができるためです。 They are concise, and ensure that all data members are copied. 自動的に生成されるコンストラクタや代入演算子は、明瞭で、かつすべてのメンバーがコピーされることが保証されます。 Copy and move constructors are also generally more efficient, because they don't require heap allocation or separate initialization and assignment steps, and they're eligible for optimizations such as copy elision . また、コピーコンストラクタやムーブコンストラクタは一般的に、より効率的に動作します。なぜならば、これらはヒープメモリは確保せず、初期化と割り当てをまとめて行い、copy elisionのような適切な最適化が行われるためです。

Move operations allow the implicit and efficient transfer of resources out of rvalue objects. ムーブ操作によって、右辺値オブジェクトから暗黙的かつ効率的にリソースを取り出すことが可能になります。 This allows a plainer coding style in some cases. これによって、よりわかりやすいコーディングスタイルを採用できる場合があります。

Some types do not need to be copyable, and providing copy operations for such types can be confusing, nonsensical, or outright incorrect. 型によってはコピーができることを必要としない場合や、コピー操作を提供しようとすること自体が理屈的におかしい場合もあります。 Types representing singleton objects (Registerer), objects tied to a specific scope (Cleanup), or closely coupled to object identity (Mutex) cannot be copied meaningfully. たとえば、(Registererのような)シングルトンのオブジェクトや、(Cleanupのような)そのスコープに紐付くオブジェクト、あるいは(Mutexのような)個別のオブジェクトと密接に繋がっているようなオブジェクトは、意味のあるコピーはできません。

Copy operations for base class types that are to be used polymorphically are hazardous, because use of them can lead to object slicing. ポリモーフィズムを使用しているような型の基底クラスに対するコピー操作は、オブジェクトのスライシングを引き起こす可能性があり危険です。 Defaulted or carelessly-implemented copy operations can be incorrect, and the resulting bugs can be confusing and difficult to diagnose. デフォルト実装や雑に実装されたコピー操作は誤ったものとなり、結果的に困惑的な診断の難しいバグを招くことがあります。

Copy constructors are invoked implicitly, which makes the invocation easy to miss. コピーコンストラクタは暗黙的に呼び出されるため、呼び出しを見落としやすいです。 This may cause confusion for programmers used to languages where pass-by-reference is conventional or mandatory. これは、参照渡しが慣習的なプログラミング言語に馴染んだプログラマにとっての混乱ポイントになるでしょう。 It may also encourage excessive copying, which can cause performance problems. また、余計なコピーを助長し、パフォーマンス上の問題になることもあります。

Provide the copy and move operations if their meaning is clear to a casual user and the copying/moving does not incur unexpected costs. カジュアルなユーザから見て、操作の意味が明確で、かつコストも十分想定できる場合、コピー操作やムーブ操作が可能なようにしてください。 If you define a copy or move constructor, define the corresponding assignment operator, and vice-versa. コピーコンストラクタやムーブコンストラクタを独自に定義する場合は、それに紐付く代入演算子も併せて実装してください(逆の場合も同様です)。 If your type is copyable, do not define move operations unless they are significantly more efficient than the corresponding copy operations. 型がコピー可能な場合は、コピーに比べて非常に効率的にムーブできる場合を除いて、ムーブ操作を定義しないでください。 If your type is not copyable, but the correctness of a move is obvious to users of the type, you may make the type move-only by defining both of the move operations. また、コピー可能ではないが、ムーブ操作の正当性が明らかなときは、それぞれのムーブ操作を定義することで、ムーブのみ可能な型とすることもできます。

If your type provides copy operations, it is recommended that you design your class so that the default implementation of those operations is correct. 型がコピー操作をサポートする場合、できるだけコンパイラによるデフォルト実装が正しい操作となるようにクラスをデザインしてください。 Remember to review the correctness of any defaulted operations as you would any other code, and to document that your class is copyable and/or cheaply movable if that's an API guarantee. また、他のコードと同様に、デフォルトで生成されるコピー操作の正当性についても、忘れずにレビューを行ってください。 また、クラスがコピー可能である、もしくは、ムーブのみ可能であることを忘れずにドキュメント化してください。

class Foo {
 public:
  Foo(Foo&& other) : field_(other.field) {}
  // Bad, defines only move constructor, but not operator=.

 private:
  Field field_;
};
class Foo {
 public:
  Foo(Foo&& other) : field_(other.field) {}
  // ダメ。ムーブコンストラクタだけが実装されていて、operator= がない。.

 private:
  Field field_;
};

Due to the risk of slicing, avoid providing an assignment operator or public copy/move constructor for a class that's intended to be derived from (and avoid deriving from a class with such members). スライシングのリスクがあるため、継承されることを目的としているクラスは、publicなコピー・ムーブコンストラクタ、コピー・ムーブ代入演算子を提供しないでください。また、それらの操作を提供しているクラスから派生することは避けてください。 If your base class needs to be copyable, provide a public virtual Clone() method, and a protected copy constructor that derived classes can use to implement it. 基底クラスをコピー可能としたい場合、public virtualなClone()メソッドを提供するようにしてください。 また、protectedなコピーコンストラクタを提供し、派生クラスのコピーの実装がそれを利用できるようにしておいてください。

If you do not want to support copy/move operations on your type, explicitly disable them using = delete in the public: section: 型にコピー操作・ムーブ操作をサポートさせたくないときは、以下の例のように、public:セクション内において= deleteを使って、明示的にそれらを無効にしてください。

// MyClass is neither copyable nor movable.
MyClass(const MyClass&) = delete;
MyClass& operator=(const MyClass&) = delete;
// MyClassは、コピーもムーブも不可
MyClass(const MyClass&) = delete;
MyClass& operator=(const MyClass&) = delete;

構造体かクラスか

Use a struct only for passive objects that carry data; everything else is a class. structはデータを運ぶための受け身的なオブジェクトにのみ使用し、それ以外はclassを使用してください。

The struct and class keywords behave almost identically in C++. structclassは、C++においてほとんど同じです。 We add our own semantic meanings to each keyword, so you should use the appropriate keyword for the data-type you're defining. 我々は、それぞれのキーワードに独自の意味づけをしています。そのため、定義されるデータの種類に応じて適切なキーワードを用いなくてはなりません。

structs should be used for passive objects that carry data, and may have associated constants, but lack any functionality other than access/setting the data members. structは、データを運ぶためだけの受け身的なオブジェクトに使います。structは、関連する定数を持つことはできますが、それ以外はデータのGetterやSetterを除いて、何ら機能的なものを持ちません。 The accessing/setting of fields is done by directly accessing the fields rather than through method invocations. データの取得・設定は、メソッド呼び出しではなく、フィールドに直接アクセスして行います。 Methods should not provide behavior but should only be used to set up the data members, e.g., constructor, destructor, Initialize(), Reset(), Validate(). データメンバーを設定する以外のメソッドは持たせてはなりません。 たとえば、コンストラクタ、デストラクタ、Initialize()Reset()Validate()などです。

If more functionality is required, a class is more appropriate. より機能的なものが要求される場合は、classの方が適切です。 If in doubt, make it a class. 迷ったらclassにしましょう。

For consistency with STL, you can use struct instead of class for functors and traits. STLとの一貫性を持たせるため、ファンクタやtraitsについては、structを使ってもかまいません。

Note that member variables in structs and classes have different naming rules. 構造体とクラスでは、命名規則が異なることに注意してください。

継承

Composition is often more appropriate than inheritance. しばしば、継承より抱合(コンポジション)の方が適切な場合もあります。 When using inheritance, make it public. 継承を使うのであれば、必ずpublicにします。

When a sub-class inherits from a base class, it includes the definitions of all the data and operations that the parent base class defines. 派生クラスが基底クラスから継承するとき、派生クラスは親となる基底クラスで定義されているすべてのデータと操作の定義を含むようになります。 In practice, inheritance is used in two major ways in C++: implementation inheritance, in which actual code is inherited by the child, and interface inheritance, in which only method names are inherited. 実際には、C++の継承は2種類の方法があります。実際のコードが継承される「実装の継承」と、メソッド名だけが継承される「インターフェースの継承」です。

Implementation inheritance reduces code size by re-using the base class code as it specializes an existing type. 実装の継承は、基底クラスのコードを再利用するため、コードのサイズが小さくなります。 Because inheritance is a compile-time declaration, you and the compiler can understand the operation and detect errors. 継承はコンパイル時の宣言であるため、コンパイラは操作を理解し、エラーを検出します。 Interface inheritance can be used to programmatically enforce that a class expose a particular API. インターフェースの継承は、プログラム的に、クラスが特定のAPIを公開することを強制するために使用します。 Again, the compiler can detect errors, in this case, when a class does not define a necessary method of the API. 同様に、コンパイラは、クラスが必要なメソッドを定義していない場合に、それをエラーとして検出します。

For implementation inheritance, because the code implementing a sub-class is spread between the base and the sub-class, it can be more difficult to understand an implementation. 実装の継承においては、派生クラスの実装が基底クラスと派生クラスとの間に分離するため、実装を理解するのをより難しくするかもしれません。 The sub-class cannot override functions that are not virtual, so the sub-class cannot change implementation. 派生クラスは、基底クラスでvirtualとして宣言されていないものをオーバーライドすることはできず、実装を変えることはできません。 The base class may also define some data members, so that specifies physical layout of the base class. また、基底クラスはデータメンバを定義しているかもしれず、それによって基底クラスの物理的なレイアウトも決まってしまいます。

All inheritance should be public. すべての継承はpublicで行います。 If you want to do private inheritance, you should be including an instance of the base class as a member instead. privateな継承を行いたい場合は、継承の代わりに基底クラスのインスタンスをメンバーとして持つようにしてください。

Do not overuse implementation inheritance. 実装の継承を使いすぎないでください。 Composition is often more appropriate. 抱合(コンポジション)の方が適切な場合もしばしばあります。 Try to restrict use of inheritance to the "is-a" case: Bar subclasses Foo if it can reasonably be said that Bar "is a kind of" Foo. 継承は is-a 関係が成立する場合のみ使うようにしてください。 たとえばFooを継承してBarを作ってよいのは、理屈の上で「BarFooの一種」といえる時だけです。

Make your destructor virtual if necessary. 必要に応じてデストラクタはvirtualにしてください。 If your class has virtual methods, its destructor should be virtual. もし、クラスが仮想関数を持っているのであれば、デストラクタも仮想でなくてはなりません。

Limit the use of protected to those member functions that might need to be accessed from subclasses. protectedは、派生クラスからアクセスされるメンバ関数だけにとどめてください。 Note that data members should be private . データメンバはprivateとするようにしてください.

Explicitly annotate overrides of virtual functions or virtual destructors with an override or (less frequently) final specifier. オーバーライドする仮想関数や仮想デストラクタには、明示的にoverrideあるいはfinal指定子をつけてください。 Older (pre-C++11) code will use the virtual keyword as an inferior alternative annotation. 古い(C++11より前の)コードでは、劣っていますが代替としてvirtualキーワードをつけてください。 For clarity, use exactly one of override, final, or virtual when declaring an override. 明快さのため、オーバーライドするときには、必ずoverridefinalvirtualのいずれかのキーワードを使用してください。 Rationale: A function or destructor marked override or final that is not an override of a base class virtual function will not compile, and this helps catch common errors. overridefinalでマークされた関数やデスクトラクタは、基底クラスの仮想関数をオーバーライドしていないときにコンパイルできなくなるため、問題に気づきやすくなります。 The specifiers serve as documentation; if no specifier is present, the reader has to check all ancestors of the class in question to determine if the function or destructor is virtual or not. これらの指定子はドキュメントの役割も果たします。もし、指定子がない場合、コードの読者は関数やデストラクタが仮想なのかそうでないのかを解決するためには、すべての継承元をたどって調べなくてはならなくなります。

多重継承

Only very rarely is multiple implementation inheritance actually useful. 実装の継承において、多重継承が有用なことはほとんどありません。 We allow multiple inheritance only when at most one of the base classes has an implementation; all other base classes must be pure interface classes tagged with the Interface suffix. 多重継承の使用が認められるのは、基底クラスのうち実装を持つものが多くとも1つまでで、他の基底クラスはすべて Interface接尾辞でタグ付けされた純粋なインターフェースクラスであるときにのみに限定されます。

Multiple inheritance allows a sub-class to have more than one base class. 多重継承により、複数の基底クラスを持った派生クラスを作ることができます。 We distinguish between base classes that are pure interfaces and those that have an implementation. ここでは、基底クラスを純粋インターフェース実装を持ったものに分類して考えます。

Multiple implementation inheritance may let you re-use even more code than single inheritance (see Inheritance). 実装の多重継承は、単一の継承よりもたくさんのコードを再利用できるかもしれません(参考:継承)。

Only very rarely is multiple implementation inheritance actually useful. 実際のところ、実装の多重継承が役に立つことはほとんどありません。 When multiple implementation inheritance seems like the solution, you can usually find a different, more explicit, and cleaner solution. 多重継承が問題の答えに見えたとしても、たいていは、もっと明示的できれいな別の方法がきっとあるはずです。

Multiple inheritance is allowed only when all superclasses, with the possible exception of the first one, are pure interfaces. 多重継承が認められるのは、1つめの基底クラスを除いて、他のすべての基底クラスが純粋なインターフェースであるときのみです。 In order to ensure that they remain pure interfaces, they must end with the Interface suffix. クラスが純粋インターフェースであることを保証するために、それらのクラスはInterface接尾辞を持っていなくてはなりません。

There is an exception to this rule on Windows. このルールにはWindowsに関する例外があります。

インターフェース

Classes that satisfy certain conditions are allowed, but not required, to end with an Interface suffix. いくつかの特定の条件を満たすクラスは、クラス名をInterface接尾辞で終わることができます(が、必須ではありません)。

A class is a pure interface if it meets the following requirements: クラスが次の要件を満たすとき、クラスは純粋なインターフェースであると言います。

  • It has only public pure virtual (" = 0 ") methods and static methods (but see below for destructor). public な純粋仮想関数( = 0で宣言された関数)と、静的なメンバ関数(と次で説明するデストラクタ)しかもたない。
  • It may not have non-static data members. 静的でないデータメンバを持たない。
  • It need not have any constructors defined. いかなるコンストラクタも定義されていない。 If a constructor is provided, it must take no arguments and it must be protected. コンストラクタが定義されている場合は、引数をとらず、protectedでなくてはならない。
  • If it is a subclass, it may only be derived from classes that satisfy these conditions and are tagged with the Interface suffix. クラスが派生クラスである場合には、基底とするクラスが、これら同じ条件を満たしていて、かつ、Interface接尾辞でタグ付けされていなくてはならない。

An interface class can never be directly instantiated because of the pure virtual method(s) it declares. インターフェースクラスは、それ自身が純粋仮想関数を宣言しているため、直接インスタンス化されることはありません。 To make sure all implementations of the interface can be destroyed correctly, the interface must also declare a virtual destructor (in an exception to the first rule, this should not be pure). インターフェースの持つすべての実装が正しく破壊されることを保証するために、インターフェースは仮想デストラクタを宣言しなくてはなりません(これは、最初のルールに対する唯一の例外として、定義を持たなくてはなりません)。 See Stroustrup, The C++ Programming Language , 3rd edition, section 12.4 for details. 詳細はStroustrup著 The C++ Programming Language, 3rd edition セクション 12.4 を参照してください。

Tagging a class with the Interface suffix lets others know that they must not add implemented methods or non static data members. クラスをInterfaceでタグ付けすることで、他のプログラマに対して、このクラスに実装や静的でないメンバ変数を追加してはならないということを伝えられます。 This is particularly important in the case of multiple inheritance. これは特に、多重継承される場合において重要なことです。 Additionally, the interface concept is already well-understood by Java programmers. 加えて、インターフェースはJavaプログラマの間ではよく知られているコンセプトです。

The Interface suffix lengthens the class name, which can make it harder to read and understand. Interfaceという接尾辞をつけると、クラス名が長くなり、読みにくく、理解にしくくなるかもしれません。 Also, the interface property may be considered an implementation detail that shouldn't be exposed to clients. また、インターフェースの性質は、クライアントに対して公開すべきでない実装の詳細であると考えることもできます。

A class may end with Interface only if it meets the above requirements. クラスが上記の要件を満たす場合はInterface接尾辞をつけることができます。 We do not require the converse, however: classes that meet the above requirements are not required to end with Interface. 逆の要件はありません。つまり、上記の要件を満たすクラスがInterface接尾辞を持たなくてはならないということはありません。

演算子のオーバーロード

Overload operators judiciously. 演算子のオーバーロードは慎重に行わなくてはなりません。 Do not create user-defined literals. ユーザ定義のリテラルは作ってはいけません。

C++ permits user code to declare overloaded versions of the built-in operators using the operator keyword, so long as one of the parameters is a user-defined type. C++では、operatorキーワードを使うことで、ユーザ定義の型を引数とした組み込み演算子のオーバーロードを宣言することができます。 The operator keyword also permits user code to define new kinds of literals using operator"", and to define type-conversion functions such as operator bool(). また、operatorキーワードは、operator""を用いることで新しいリテラルを定義することもできます。operator bool()など、型変換を定義することもできます。

Operator overloading can make code more concise and intuitive by enabling user-defined types to behave the same as built-in types. 演算子のオーバーロードは、ユーザ定義の型に組み込み型と同様の振る舞いをさせることができるようになるため、コードを簡潔で直感的にすることができます。 Overloaded operators are the idiomatic names for certain operations (e.g. ==, <, =, and <<), and adhering to those conventions can make user-defined types more readable and enable them to interoperate with libraries that expect those names. オーバーロードされた演算子は、決まった操作に対して慣例に沿った名前を与えます(==<=<<など)。これらの慣例に従うことは、ユーザ定義の型に対する可読性を向上させ、それらの名前を期待しているライブラリとの相互運用性を高めることができます。

User-defined literals are a very concise notation for creating objects of user-defined types. ユーザ定義のリテラルは、ユーザ定義のオブジェクトを生成する非常に賢明な記載方法です。

  • Providing a correct, consistent, and unsurprising set of operator overloads requires some care, and failure to do so can lead to confusion and bugs. 正しい、一貫性を持った、よくある形の演算子のセットを提供するためには、細かな注意が必要となり、失敗すると、混乱やバグを引き起こしかねません。
  • Overuse of operators can lead to obfuscated code, particularly if the overloaded operator's semantics don't follow convention. 演算子の過剰な使用、特に、慣例に従わないような意味を演算子に持たせた場合、コードがわかりにくくなります。
  • The hazards of function overloading apply just as much to operator overloading, if not more so. 関数のオーバーロードを行う場合と同様の危険性が、演算子のオーバーロードを行う場合にも当てはまります。
  • Operator overloads can fool our intuition into thinking that expensive operations are cheap, built-in operations. 演算子のオーバーロードは、本来高コストな処理を組み込み演算子のように低コストに見せかけてしまうことができます。このことは私たちの直感に反します。
  • Finding the call sites for overloaded operators may requre a search tool that's aware of C++ syntax, rather than e.g. grep. オーバーロードされた演算子の呼び出し元を検索しようとする場合、grepでは要をなさず、C++の文法を理解するツールを使用する必要があります。
  • If you get the argument type of an overloaded operator wrong, you may get a different overload rather than a compiler error. オーバーロードされた演算子の引数の型を間違えたとき、単にコンパイルエラーになるのであればまだよいのですが、エラーにならず別の演算子の呼び出しに解決されてしまうかもしれません。 For example, foo < bar may do one thing, while &foo < &bar does something totally different. たとえば、foo < bar&foo < &barはまったく意味の異なる演算です。
  • Certain operator overloads are inherently hazardous. 演算子の中には、オーバーロードすること自体に潜在的な危険性をはらんでいるものがあります。 Overloading unary & can cause the same code to have different meanings depending on whether the overload declaration is visible. 単項演算子&のオーバーロードは、その宣言が見えているかどうかで、意味が変わってしまうことになります。 Overloads of &&, ||, and , (comma) cannot match the evaluation-order semantics of the built-in operators. また、&&, ||, and ,(カンマ演算子)をオーバーロードした場合、組み込み演算子で定められている式の評価順序と一致させることはできません。
  • Operators are often defined outside the class, so there's a risk of different files introducing different definitions of the same operator. オペレータはしばしばクラスの外で定義されますが、その場合、異なるファイルにある異なる定義を引き込んでしまう危険性があります。 If both definitions are linked into the same binary, this results in undefined behavior, which can manifest as subtle run-time bugs. 同じバイナリ内でそれらの実装の異なるオペレーターの両方がリンクされてしまった場合、未定義の動作を引き起こし、細かいバグを引き起こすことになるでしょう。
  • User-defined literals allow the creation of new syntactic forms that are unfamiliar even to experienced C++ programmers. ユーザ定義のリテラルは、文法的に新しい形式を生み出しますが、それらは十分経験を積んだC++プログラマにとってさえ親しみの薄いものです。

Define overloaded operators only if their meaning is obvious, unsurprising, and consistent with the corresponding built-in operators. 演算子のオーバーロードを定義できるのは、意味が明らかであり、動作を予測可能であり、かつ、組み込み演算子との一貫性が保てる場合のみに限定します。 For example, use | as a bitwise- or logical-or, not as a shell-style pipe. たとえば、|は、ビット和か論理和の意味でのみ使い、シェルでいうパイプのような意味では使いません。

Define operators only on your own types. 演算子は自分の型に対するもののみ定義してください。 More precisely, define them in the same headers, .cc files, and namespaces as the types they operate on. より厳密には、それらは型と同じヘッダか.ccファイル、そして型と同じ名前空間の中で定義してください。 That way, the operators are available wherever the type is, minimizing the risk of multiple definitions. そうすることで、型が利用可能なところでは演算子も利用できるようになり、演算子の多重定義に関するリスクを最小限にとどめることができます。 If possible, avoid defining operators as templates, because they must satisfy this rule for any possible template arguments. 可能であれば、演算子をテンプレートとして定義するのは避けてください。テンプレートとして宣言された演算子は、取り得る限りすべてのテンプレート引数において、ここで述べているルールを満たさなくてはなりません。 If you define an operator, also define any related operators that make sense, and make sure they are defined consistently. ある演算子を定義する場合、関連するオペレータも定義し、必ず一貫性を持たせるようにしてください。 For example, if you overload <, overload all the comparison operators, and make sure < and > never return true for the same arguments. たとえば、<をオーバーロードしたのであれば、すべての比較演算子をオーバーロードし、ある引数の組に対する比較演算<>の結果が両方ともtrueになるようなことがないようにしてください。

Prefer to define non-modifying binary operators as non-member functions. 引数に対して変更を伴わない二項演算子は、非メンバ関数として定義されることが好ましいです。 If a binary operator is defined as a class member, implicit conversions will apply to the right-hand argument, but not the left-hand one. 仮に二項演算子がクラスのメンバとして定義された場合、演算子の右辺については暗黙的型変換を適用できますが、左辺には適用できなくなってしまいます。 It will confuse your users if a < b compiles but b < a doesn't. a < bはコンパイルできるけどb < aはコンパイルできないのような状況は、ユーザを混乱させることになります。

Don't go out of your way to avoid defining operator overloads. 演算子のオーバーロードをわざわざ避けるようなことはしないでください。 For example, prefer to define ==, =, and <<, rather than Equals(), CopyFrom(), and PrintTo(). Equals()CopyFrom()PrintTo()などを実装するよりも、===<<を定義するようにしましょう。 Conversely, don't define operator overloads just because other libraries expect them. 逆に、他のライブラリを使いたいがためだけに演算子をオーバーロードすることは避けてください。 For example, if your type doesn't have a natural ordering, but you want to store it in a std::set, use a custom comparator rather than overloading <. たとえば、値同士の順序をつけられないのに、std::setに入れたいがためだけに<をオーバーロードしてはいけません。このような型をstd::setに入れたい場合は、カスタムの比較子(comparator)を使うようにします。

Do not overload &&, ||, , (comma), or unary &. 演算子&&||, (カンマ演算子)、単項演算子&はオーバーロードをしてはいけません。 Do not overload operator"", i.e. do not introduce user-defined literals. また、operator""のオーバーロードもしてはいけません。つまり、ユーザ定義リテラルを導入してはいけません。

Type conversion operators are covered in the section on implicit conversions. 型変換演算子については暗黙的型変換のセクションでカバーします。 The = operator is covered in the section on copy constructors. =演算子はコピーコンストラクタのセクションでカバーします。 Overloading << for use with streams is covered in the section on streams. <<をストリーム用途で使うオーバーロードについては、ストリームでカバーします。 See also the rules on function overloading, which apply to operator overloading as well. そのほか、演算子のオーバーロードは関数のオーバーロードにあるルールも同様に適用されますので、あわせてそちらも参照してください。

アクセス制限

Make data members private, unless they are static const (and follow the naming convention for constants ). データメンバーはprivateとしてください。 ただし、static constであるもの(定数に関する命名規則も参照)を除きます。 For technical reasons, we allow data members of a test fixture class to be protected when using Google Test ). 技術的な理由により、Google Testを使う場合のテスト用のクラスのデータメンバはprotectedであってもよいとします。

宣言の順序

Group similar declarations together, placing public parts earlier. 似ている宣言は1つにまとめ、public部分の先の方に置きます。

A class definition should usually start with a public: section, followed by protected:, then private:. クラスの定義は、通常はpublic:セクションから始め、protected:private:と続けます。 Omit sections that would be empty. 空になるセクションは省略してください。

Within each section, generally prefer grouping similar kinds of declarations together, and generally prefer the following order: types (including typedef, using, and nested structs and classes), constants, factory functions, constructors, assignment operators, destructor, all other methods, data members. 各セクションにおいて、似た宣言は1カ所にまとるようにしましょう。また、順序は、型(typedefusing、内部構造体・クラスを含む)、定数、ファクトリ関数、コンストラクタ、代入演算子、デストラクタ、それ以外のすべてのメソッド、データメンバ の順となるようにしましょう。

Do not put large method definitions inline in the class definition. クラス定義の中では、大きなメソッドの定義をインラインで行わないでください。 Usually, only trivial or performance-critical, and very short, methods may be defined inline. 通常は、ささいな関数、パフォーマンス的に重要な関数、非常に短い関数のみがインラインで定義されます。 See Inline Functions for more details. 詳細はインライン関数で述べます。

関数

引数の順序

When defining a function, parameter order is: inputs, then outputs. 関数を定義するときの引数の順序は入力が先、出力が後とします。

Parameters to C/C++ functions are either input to the function, output from the function, or both. C/C++の関数に渡される引数は、関数への入力であるか、関数への出力であるか、あるいはその両方です。 Input parameters are usually values or const references, while output and input/output parameters will be pointers to non-const. 入力となる引数は、通常は、値渡しか、const参照渡しです。一方で出力となる引数、あるいは入力と出力の両方となる引数は、非constなポインタとなります。 When ordering function parameters, put all input-only parameters before any output parameters. 引数の順番を決めるときは、入力のみに使われる引数を、いかなる出力の引数よりも前に配置します。 In particular, do not add new parameters to the end of the function just because they are new; place new input-only parameters before the output parameters. 特に、新しい引数を追加するときは、新しいからという理由だけで関数の最後に追加してはいけません。新しく追加する引数が入力のための引数であるのならば、それは出力引数の前に配置します。

This is not a hard-and-fast rule. これは絶対のルールではありません。 Parameters that are both input and output (often classes/structs) muddy the waters, and, as always, consistency with related functions may require you to bend the rule. 入力と出力の両方の役割を持つ引数(大抵はクラスや構造体)が存在する場合は、明確な線引きはできません。また、関連する関数との一貫性を保つためにはこのルールを曲げなくてはならないかもしれません。

関数は短く

Prefer small and focused functions. 関数は、短く、焦点を絞ったものにしましょう。

We recognize that long functions are sometimes appropriate, so no hard limit is placed on functions length. 時には長い関数の方が適切なこともあるため、関数の長さに関する固定の限界値は定めません。 If a function exceeds about 40 lines, think about whether it can be broken up without harming the structure of the program. だいたい40行程度を超えるようであれば、プログラムの構造を破壊することなく関数を分割できないか考えてみてください。

Even if your long function works perfectly now, someone modifying it in a few months may add new behavior. 長い関数が、現時点では完璧に動いていたとしても、1~2ヶ月後に誰かがそれを変更し、新しい動作を足すかもしれません。 This could result in bugs that are hard to find. その結果として見つけるのが困難なバグを引き起こすかもしれません。 Keeping your functions short and simple makes it easier for other people to read and modify your code. 関数を短くシンプルであるように保つことで、コードをより読みやすく、より変更しやすくできるのです。

You could find long and complicated functions when working with some code. 作業をしていると、長い複雑なコードに出くわすこともあるでしょう。 Do not be intimidated by modifying existing code: if working with such a function proves to be difficult, you find that errors are hard to debug, or you want to use a piece of it in several different contexts, consider breaking up the function into smaller and more manageable pieces. 既存のコードを変更することにおびえてはいけません。 そのコードを使って仕事を進めることが困難であることがわかった場合、エラーのデバッグが難しいことがわかった場合、あるいは別の文脈においてその関数の一部分だけを切り出して使いたくなった場合、関数をより小さく扱いやすい複数の断片に分割することを検討してください。

参照渡し

All parameters passed by reference must be labeled const. 参照渡しされる引数は必ずconstでなくてはなりません。

In C, if a function needs to modify a variable, the parameter must use a pointer, eg int foo(int *pval). C言語において、関数が変数を変更する必要があるときは、引数にポインタを使わなくてはなりません(例: int foo(int *pval))。 In C++, the function can alternatively declare a reference parameter: int foo(int &val). C++においては、他の方法として、参照渡しを使って関数を宣言することもできます(例:int foo(int &val))。

Defining a parameter as reference avoids ugly code like (*pval)++. 引数を参照にすることで、(*pval)++のような醜いコードを避けられます。 Necessary for some applications like copy constructors. 参照渡しは、コピーコンストラクタなど、それを必要する場面があります。 Makes it clear, unlike with pointers, that a null pointer is not a possible value. 参照渡しは、ポインタと違って、ヌルポインタが渡せないことが明確になります。

References can be confusing, as they have value syntax but pointer semantics. 参照は、値型と同じ文法のまま、ポインタと同じような意味を持つため、混乱しやすいです。

Within function parameter lists all references must be const: 関数の引数リストにおいては、以下の例のように、すべての参照はconstでなくてはなりません。

void Foo(const string &in, string *out);

In fact it is a very strong convention in Google code that input arguments are values or const references while output arguments are pointers. 実際、入力引数が値渡しかconst参照であり、出力引数がポインタであるということは、Googleのコードにおいて非常に強いしきたりになっています。 Input parameters may be const pointers, but we never allow non-const reference parameters except when required by convention, e.g., swap(). 入力引数にconstポインタが使われることはありますが、非constな参照は、swap()のような習慣的な要求がある場合を除いて、認められることはありません。

However, there are some instances where using const T* is preferable to const T& for input parameters. 入力引数にconst T&よりconst T* を使う方がよい場面もあります。 For example: たとえば、

  • You want to pass in a null pointer. ヌルポインタを渡したいとき や
  • The function saves a pointer or reference to the input. 関数が入力にポインタか参照を保存したいとき です。

Remember that most of the time input parameters are going to be specified as const T& . ほとんどの場合、入力引数はconst T&のように特殊化されます。 Using const T* instead communicates to the reader that the input is somehow treated differently. const T*という表現を使うことは、コードの読者に、ここでは入力に対して何かしら普段と違う扱い方をしますよと伝えていることになります。 So if you choose const T* rather than const T&, do so for a concrete reason; otherwise it will likely confuse readers by making them look for an explanation that doesn't exist. あなたが、const T&ではなく、const T*を選ぶときは具体的な理由が必要です。さもなくば、コードの読者が、(ポインタを使っている)ありもしない理由を探そうとしてしまうかもしれず、混乱を招くかもしれません。

関数のオーバーロード

Use overloaded functions (including constructors) only if a reader looking at a call site can get a good idea of what is happening without having to first figure out exactly which overload is being called. コンストラクタを含む関数のオーバーロードは、コードの読者が、その呼び出し元を読んだときに、具体的にどのオーバーロードが呼び出されるか正確に把握していなくとも、何が起こるか理解できるであろう場合にのみ使用できます。

You may write a function that takes a const string& and overload it with another that takes const char*. const string&を引数にとる関数と、const char*を引数にとるオーバーロードとを書くことができます。

class MyClass {
 public:
  void Analyze(const string &text);
  void Analyze(const char *text, size_t textlen);
};

Overloading can make code more intuitive by allowing an identically-named function to take different arguments. オーバーロードによって、同一名の関数に異なる引数をとらせることができるため、コードがより直感的になります。 It may be necessary for templatized code, and it can be convenient for Visitors. この機能は、テンプレート化されたコードにおいて必要とされ、また、ビジターパターンにおいても有用となるでしょう。

If a function is overloaded by the argument types alone, a reader may have to understand C++'s complex matching rules in order to tell what's going on. ある関数が引数の型だけでオーバーロードされている場合、コードの読者がそこで実際に起きることを知るためには、C++の複雑なマッチングルールについて理解していなくてはなりません。 Also many people are confused by the semantics of inheritance if a derived class overrides only some of the variants of a function. また、複数のオーバーロードを持つ仮想関数を、派生先で部分的にオーバーライドした場合の挙動は、多くの人を困惑させています。

If you want to overload a function, consider qualifying the name with some information about the arguments, e.g., AppendString(), AppendInt() rather than just Append(). 関数をオーバーロードしたくなったら、まずは名前に引数の情報をつける(たとえば、Append()の代わりに、AppendString()AppendInt()とする)やり方を検討してください。 If you are overloading a function to support variable number of arguments of the same type, consider making it take a std::vector so that the user can use an initializer list to specify the arguments. また、型は同一でも、その型の引数をいくつとるかによってオーバーロードを定義したいときは、std::vectorを引数にとるようにするやり方を検討してください。その方法ならば、ユーザは初期化子リストの形で引数を渡せます。

引数のデフォルト値

Default arguments are allowed on non-virtual functions when the default is guaranteed to always have the same value. 引数にデフォルトの値を与えられるのは、その関数が仮想関数ではなく、かつ、値が常に同じ値になることを保証できる場合に限ります。 Follow the same restrictions as for function overloading, and prefer overloaded functions if the readability gained with default arguments doesn't outweigh the downsides below. 関数のオーバーロードと同様の制限に従ってください。また、引数にデフォルト値を与えることによって得られる可読性よりも、以下に述べるマイナス面の方が勝る場合、代わりに関数のオーバーロードを使いましょう。

Often you have a function that uses default values, but occasionally you want to override the defaults. 普段はデフォルトの値で使っている関数でも、時々別の値に変えて呼び出したくなることがあります。 Default parameters allow an easy way to do this without having to define many functions for the rare exceptions. 引数にデフォルト値を与えることは、このような"時々"のための関数をたくさん定義することなく、簡単にやりたいことを実現するための手段の一つです。 Compared to overloading the function, default arguments have a cleaner syntax, with less boilerplate and a clearer distinction between 'required' and 'optional' arguments. 関数のオーバーロードと比較して、このやり方は、文法的にきれいで、より少ない例で済み、さらに、引数が必須か任意かをより明確に区別できるようにもなります。

Defaulted arguments are another way to achieve the semantics of overloaded functions, so all the reasons not to overload functions apply. 引数にデフォルト値を与える方法は、関数のオーバーロードでできることを実現する別の方法でもあるため、すべての関数をオーバーロードしない理由を適用します。

The defaults for arguments in a virtual function call are determined by the static type of the target object, and there's no guarantee that all overrides of a given function declare the same defaults. 仮想関数呼び出しにおける引数のデフォルト値は、オブジェクトの静的な型に基づいて決定されますが、その関数のすべてのオーバーライドが、同じデフォルト値とともに宣言されている保証はどこにもありません。

Default parameters are re-evaluated at each call site, which can bloat the generated code. 引数のデフォルト値は、呼び出されるごとに評価されるため、生成されるコードの量がふくれます。 Readers may also expect the default's value to be fixed at the declaration instead of varying at each call. また、コードの読者は、関数が呼び出されるたびにデフォルト値が変わるのではなく、宣言時点で決まった値に固定されていることを期待するかもしれません。

Function pointers are confusing in the presence of default arguments, since the function signature often doesn't match the call signature. 関数ポインタを引数のデフォルト値として与えると混乱の元になります。関数のシグネチャはしばしば、呼び出す際のシグネチャと一致しないことがあるからです。 Adding function overloads avoids these problems. 関数のオーバーロードであれば、これらの問題は回避することができます。

Default arguments are banned on virtual functions, where they don't work properly, and in cases where the specified default might not evaluate to the same value depending on when it was evaluated. 仮想関数における引数にデフォルト値を与えても、それらは意図した通りに動作しないため禁止とします。また、デフォルト値が評価のタイミングによって必ず同じ値にならない場合についても禁止とします。 (For example, don't write void f(int n = counter++); .) (たとえば、次のように書いてはいけません: void f(int n = counter++);)

In some other cases, default arguments can improve the readability of their function declarations enough to overcome the downsides above, so they are allowed. その他のいくつかの場合において、引数にデフォルト値を与えることで、ここまで述べた悪い点を差し引いても十分に関数宣言の可読性を高めることができる場合があります。このとき、それらの使用が認められます。 When in doubt, use overloads. 迷ったときは関数のオーバーロードを選択します。

戻り値の型を後置する関数宣言構文

Use trailing return types only where using the ordinary syntax (leading return types) is impractical or much less readable. 戻り値の型を後置する関数宣言構文は、普通の構文(戻り値の型から始まる構文)を使うことができない場合か、普通の構文では可読性に劣ってしまう場合にのみ使用します。

C++ allows two different forms of function declarations. C++では、2種類の異なる関数宣言の構文が認められています。 In the older form, the return type appears before the function name. For example: 古い形では、次の例のように、戻り値の型が関数名より先にきます。

int foo(int x);

The new form, introduced in C++11, uses the auto keyword before the function name and a trailing return type after the argument list. C++で導入された新しい形は、autoキーワードを関数名の前に置き、戻り値の型を引数リストの後に置きます。 For example, the declaration above could equivalently be written: 例として、先ほどの宣言と等価な宣言は次のようになります。

auto foo(int x) -> int;

The trailing return type is in the function's scope. この戻り値の型は関数内スコープとなります。 This doesn't make a difference for a simple case like int but it matters for more complicated cases, like types declared in class scope or types written in terms of the function parameters. intのように単純な場合はこれらに違いはありませんが、型がより複雑な場合にはこれは重要となってきます。 たとえば、型がクラススコープで宣言されている場合や、型が関数の引数によって決まったりする場合です。

Trailing return types are the only way to explicitly specify the return type of a lambda expression. 戻り値の型を後置する構文は、ラムダ式の戻り値の型を明示できる唯一の方法です。 In some cases the compiler is able to deduce a lambda's return type, but not in all cases. コンパイラはラムダ式の戻り値の型を推論できる場合がありますが、常にそれができるわけではありません。 Even when the compiler can deduce it automatically, sometimes specifying it explicitly would be clearer for readers. コンパイラが自動的に型を推論できる場合であっても、型を明示することでコードの可読性を向上させる場合もあります。

Sometimes it's easier and more readable to specify a return type after the function's parameter list has already appeared. 時に、戻り値の型を関数の引数の後ろに明示することで、より簡単で可読性が高くなることがあります。 This is particularly true when the return type depends on template parameters. 特に、戻り値の型がテンプレートパラメータによって決まる場合にはこのことが言えます。 For example: 次の例を見てください。

template <class T, class U> auto add(T t, U u) -> decltype(t + u);
versus
template <class T, class U> decltype(declval<T&>() + declval<U&>()) add(T t, U u);

Trailing return type syntax is relatively new and it has no analogue in C++-like languages like C and Java, so some readers may find it unfamiliar. 戻り値の型を後置する構文は、比較的新しく、C++系言語(C言語やJavaなど)には類似の構文がありません。このため、コードの読者にとってなじみが薄いかもしれません。

Existing code bases have an enormous number of function declarations that aren't going to get changed to use the new syntax, so the realistic choices are using the old syntax only or using a mixture of the two. 既存のコードベースには既に膨大な数の関数宣言があり、それらが新しい構文に替わることはないでしょう。このため、現実的には、古い構文と新しい構文との両方を混合させて使っていくという道を選択することになります。 Using a single version is better for uniformity of style. スタイルの一様性のためには、1種類だけを使うことが好ましいです。

In most cases, continue to use the older style of function declaration where the return type goes before the function name. ほとんどの場合において、旧来からある、戻り値の型が関数名より先に来る関数宣言の構文を使い続けてください。 Use the new trailing-return-type form only in cases where it's required (such as lambdas) or where, by putting the type after the function's parameter list, it allows you to write the type in a much more readable way. 新しい構文を使用してよいのは、それがどうしても必要な場合(ラムダ式のような)と、引数のリストの後ろに戻り値の型を置くことで可読性を大きく向上させられる場合に限定します。 The latter case should be rare; it's mostly an issue in fairly complicated template code, which is discouraged in most cases. 後者の状況はまれです。というのも、大抵、複雑すぎるテンプレートのコードが問題なのであって、それらのほとんどは解消できるからです。

Google特有のマジック

There are various tricks and utilities that we use to make C++ code more robust, and various ways we use C++ that may differ from what you see elsewhere. 我々はC++のコードをより堅牢にするためのトリックやユーティリティを使用しています。 我々が使用する様々な手法は、一般的に見られるC++の使い方とは異なっているかもしれません。

スマートポインタの所有権

Prefer to have single, fixed owners for dynamically allocated objects. 動的に確保されるオブジェクトの所有者は、単一かつ固定されるようにしましょう。 Prefer to transfer ownership with smart pointers. オブジェクトの所有権を移すときは、スマートポインタを使用しましょう。

"Ownership" is a bookkeeping technique for managing dynamically allocated memory (and other resources). "所有権"は、動的に確保されるメモリ(や他のリソース)を管理するための帳簿的なテクニックの一つです。 The owner of a dynamically allocated object is an object or function that is responsible for ensuring that it is deleted when no longer needed. 動的に確保されるオブジェクトの所有者は、1つのオブジェクトか関数であり、オブジェクトが不要になったときにそれを解放する責任を負います。 Ownership can sometimes be shared, in which case the last owner is typically responsible for deleting it. 所有権は時には共有されることもあります。その場合、一般的に最後の所有者が解放の責任を負います。 Even when ownership is not shared, it can be transferred from one piece of code to another. 所有権は、共有まではされない場合でも、あるコードから他のコードへと移されることがあります。

"Smart" pointers are classes that act like pointers, e.g. by overloading the * and -> operators. "スマート"ポインタとは、ポインタのように振る舞うクラスです(たとえば演算子*->をオーバーロードしています)。 Some smart pointer types can be used to automate ownership bookkeeping, to ensure these responsibilities are met. いくつかのスマートポインタは、このような解放の責任を確実にするための所有権管理を自動的に行うために使われるものがあります。 std::unique_ptr is a smart pointer type introduced in C++11, which expresses exclusive ownership of a dynamically allocated object; the object is deleted when the std::unique_ptr goes out of scope. std::unique_ptrは、スマートポインタの一種で、C++11で導入されました。このスマートポインタは、動的に確保されたオブジェクトに対する排他的な所有権を表します。std::unique_ptrによって所有されるオブジェクトは、std::unique_ptrがスコープの外に出たときにdeleteされます。 It cannot be copied, but can be moved to represent ownership transfer. std::unique_ptrをコピーすることはできませんが、担当する所有権を移動させることはできます。 std::shared_ptr is a smart pointer type that expresses shared ownership of a dynamically allocated object. std::shared_ptrは、動的に確保されたオブジェクトの所有権を他者と共有することを表すために使われるスマートポインタです。 std::shared_ptrs can be copied; ownership of the object is shared among all copies, and the object is deleted when the last std::shared_ptr is destroyed. std::shared_ptrはコピーすることができます。オブジェクトの所有権はすべてのコピーの間で共有され、オブジェクトは最後のstd::shared_ptrが破壊されるときにdeleteされます。

  • It's virtually impossible to manage dynamically allocated memory without some sort of ownership logic. 所有権の概念がなければ、動的に確保されるメモリを管理するのは実質的に不可能です。
  • Transferring ownership of an object can be cheaper than copying it (if copying it is even possible). 所有権を移すだけであれば、オブジェクトをコピーするよりも低コストとなるでしょう。
  • Transferring ownership can be simpler than 'borrowing' a pointer or reference, because it reduces the need to coordinate the lifetime of the object between the two users. オブジェクトの所有権を移すことは、参照やポインタを「借りてくる」よりも単純です。なぜならば、そのオブジェクトを扱う二者間での、オブジェクトの生存期間に関する認識合わせの必要性を減らすからです。
  • Smart pointers can improve readability by making ownership logic explicit, self-documenting, and unambiguous. スマートポインタは、所有権を明示化し、それ自体にドキュメントの意味合いを持たせられるため、可読性が向上します。
  • Smart pointers can eliminate manual ownership bookkeeping, simplifying the code and ruling out large classes of errors. スマートポインタは手作業による所有権管理をなくし、コードを単純化し、エラーのうち大きな分類を除外することができます。
  • For const objects, shared ownership can be a simple and efficient alternative to deep copying. constなオブジェクトについていえば、所有権を共有することは、単純かつ効率的なディープコピーの代替手段となります。
  • Ownership must be represented and transferred via pointers (whether smart or plain). 所有権は、スマートポインタであろうと生のポインタであろうと、何らかのポインタによって扱われ、ポインタ間で受け渡しが行われます。 Pointer semantics are more complicated than value semantics, especially in APIs: you have to worry not just about ownership, but also aliasing, lifetime, and mutability, among other issues. ポインタの概念は値を直接扱うよりも複雑で、特にAPIの層では、所有権だけではなく、エイリアシング、ライフタイム、ミュータビリティ、などについても気にしなくてはなりません。
  • The performance costs of value semantics are often overestimated, so the performance benefits of ownership transfer might not justify the readability and complexity costs. 値を直接扱うときのパフォーマンスコストはしばしば想定よりも高く見積もられがちです。所有権を移す方法を選択することで得られるパフォーマンス上のメリットは、それによる可読性の低下や複雑化のコストに見合わないかもしれません。
  • APIs that transfer ownership force their clients into a single memory management model. 所有権を移すAPIは、その使用者にシングルメモリマネジメントモデルを強制します。
  • Code using smart pointers is less explicit about where the resource releases take place. スマートポインタ使っているコードは、リソースがいつどこで解放されるかの明示性が低下します。
  • std::unique_ptr expresses ownership transfer using C++11's move semantics, which are relatively new and may confuse some programmers. std::unique_ptr は、C+11のムーブのセマンティクスを使って所有権を移します。ムーブの概念は比較的新しいため、プログラマを混乱させるかもしれません。
  • Shared ownership can be a tempting alternative to careful ownership design, obfuscating the design of a system. 所有権に関するデザインを注意深く行うのに比べて、単純に所有権を共有させて済ませてしまうことは、魅惑的な代替手段に見える場合があります。そして、それはシステムのデザインを曖昧にしてしまうことに繋がります。
  • Shared ownership requires explicit bookkeeping at run-time, which can be costly. 所有権を共有させると、実行時に明示的な所有権を管理を行うことになり、このためのコストが高くつく場合があります。
  • In some cases (e.g. cyclic references), objects with shared ownership may never be deleted. たとえば循環参照のように、所有権を共有されたオブジェクトが決してdeleteされない状態に陥ることがあります。
  • Smart pointers are not perfect substitutes for plain pointers. スマートポインタは生のポインタに対する完璧な代替手段ではありません。

If dynamic allocation is necessary, prefer to keep ownership with the code that allocated it. 動的なオブジェクトの確保が必要な場合、その所有権はそれを確保したコードが持つようにしましょう。 If other code needs access to the object, consider passing it a copy, or passing a pointer or reference without transferring ownership. 他のコードがそのオブジェクトにアクセスする必要がある場合は、単にオブジェクトのコピーを渡すか、所有権の移動なしにポインタや参照を渡す方法を検討してください。 Prefer to use std::unique_ptr to make ownership transfer explicit. 所有権の移動を明示的に行うためには、std::unique_ptrを使うようにしましょう。 For example: 以下に例を示します。

std::unique_ptr<Foo> FooFactory();
void FooConsumer(std::unique_ptr<Foo> ptr);

Do not design your code to use shared ownership without a very good reason. 非常に良い理由がない限り、オブジェクトの所有権を共有させるデザインにしてはいけません。 One such reason is to avoid expensive copy operations, but you should only do this if the performance benefits are significant, and the underlying object is immutable (i.e. std::shared_ptr<const Foo>). そのような理由としては、高価なコピーを避けるためといったものがあげられますが、所有権の共有は、パフォーマンス上の利益が大きく、かつ対象のオブジェクトが不変である場合にのみ行ってください(言い換えると、std::shared_ptr<const Foo>)。 If you do use shared ownership, prefer to use std::shared_ptr. 所有権を共有したい場合、std::shared_ptrを使いましょう。

Never use std::auto_ptr. std::auto_ptrを使ってはなりません。 Instead, use std::unique_ptr. 代わりに、std::unique_ptrを使いましょう。

cpplint

Use cpplint.py to detect style errors. スタイルに関する問題を検出するため、cpplint.pyを使ってください。

cpplint.py is a tool that reads a source file and identifies many style errors. cpplint.pyは、ソースファイルを読み、スタイルに関するたくさんのエラーを識別してくれるツールです。 It is not perfect, and has both false positives and false negatives, but it is still a valuable tool. このツールは完璧ではなく、誤診もありますが、それでも価値があります。 False positives can be ignored by putting // NOLINT at the end of the line or // NOLINTNEXTLINE in the previous line. 偽陽性の診断される場合は、行末に// NOLINTを書くか、前の行に// NOLINTNEXTLINEを記載すれば、無視されます。

Some projects have instructions on how to run cpplint.py from their project tools. いくつかのプロジェクトにおいては、プロジェクトのツールからcpplint.pyを起動するやり方が用意されています。 If the project you are contributing to does not, you can download cpplint.py separately. あなたのプロジェクトでそのような環境が用意されていない場合はcpplint.pyから個別にダウンロードすることができます。

その他のC++の機能

右辺値参照

Use rvalue references only to define move constructors and move assignment operators, or for perfect forwarding. 右辺値参照はムーブコンストラクタとムーブ代入演算子を定義するときと、Perfect Forwardingを行う場合のみに使用できます。

Rvalue references are a type of reference that can only bind to temporary objects. 右辺値参照とは、一時オブジェクトにのみ紐付く参照のことです。 The syntax is similar to traditional reference syntax. 文法は従来からある参照に似ています。 For example, void f(string&& s); declares a function whose argument is an rvalue reference to a string. たとえば、void f(string&& s);は、stringの右辺値参照を引数にとる関数を宣言しています。

  • Defining a move constructor (a constructor taking an rvalue reference to the class type) makes it possible to move a value instead of copying it. ムーブコンストラクタ(クラスの右辺値参照をとるコンストラクタ)を定義すると、値をコピーではなくムーブすることができるようになります。 If v1 is a std::vector<string>, for example, then auto v2(std::move(v1)) will probably just result in some simple pointer manipulation instead of copying a large amount of data. v1std::vector<string>であるとき、たとえば、auto v2(std::move(v1))は、大量のデータをコピーする代わりに、単なるポインタ操作だけで済ませることができるでしょう。 In some cases this can result in a major performance improvement. いくつかの場合において、これらは大きなパフォーマンス向上に繋がります。
  • Rvalue references make it possible to write a generic function wrapper that forwards its arguments to another function, and works whether or not its arguments are temporary objects. (This is sometimes called "perfect forwarding".) 右辺値参照によって、引数を転送(forward)する汎用的な関数のラッパーを書くことができるようになります。これは、引数が一時オブジェクトであるか否かにかかわらず動作します。これをPerfect Forwardingと呼ぶこともあります。
  • Rvalue references make it possible to implement types that are movable but not copyable, which can be useful for types that have no sensible definition of copying but where you might still want to pass them as function arguments, put them in containers, etc. 右辺値参照によって、ムーブはできるがコピーできない型を作ることができるようになります。このような型は、細やかなコピー操作の定義を持たないにも関わらず、関数の引数に渡したり、コンテナに格納したりできるため便利です。
  • std::move is necessary to make effective use of some standard-library types, such as std::unique_ptr. std::moveは、std::unique_ptrのような、いくつかの標準ライブラリを効率的に使うために必要とされます。
  • Rvalue references are a relatively new feature (introduced as part of C++11), and not yet widely understood. 右辺値参照は、C++11の一部として導入された比較的新しい機能のため、まだ広く理解されていません。 Rules like reference collapsing, and automatic synthesis of move constructors, are complicated. 参照が破壊される、ムーブコンストラクタが自動生成されるなどのルールは難しいものです。

Use rvalue references only to define move constructors and move assignment operators (as described in Copyable and Movable Types ) and, in conjunction with std::forward, to support perfect forwarding. 右辺値参照は、ムーブコンストラクタ・ムーブ代入演算子(詳細はコピー可能な型・ムーブ可能な型)を定義するため、もしくは、Perfect Forwardingをサポートするためにstd::forwardとあわせて使う場合にのみ使用してください。 You may use std::move to express moving a value from one object to another rather than copying it. オブジェクトからオブジェクトへ、値が(コピーではなく)ムーブすることを表現するためにstd::moveを使用しても構いません。

フレンド

We allow use of friend classes and functions, within reason. それが理に叶っている場合、friendクラスやfriend関数を使用できます。

Friends should usually be defined in the same file so that the reader does not have to look in another file to find uses of the private members of a class. コードの読者が、クラスのprivateメンバーの扱い方を、他のファイルまで探しに行かなくてもいいように、通常は、クラスのフレンドは同じファイル内に定義してください。 A common use of friend is to have a FooBuilder class be a friend of Foo so that it can construct the inner state of Foo correctly, without exposing this state to the world. friendのよくある使い方は、FooBuilderFooのフレンドにして、FooBuilderFooの内部状態を(publicに晒すことなく)正しく構築できるようにするといったようなものです。 In some cases it may be useful to make a unittest class a friend of the class it tests. あるいは、クラスのユニットテストを行う別のクラスがフレンドに指定されていると便利な場合もあります。

Friends extend, but do not break, the encapsulation boundary of a class. フレンドはクラスのカプセル化の壁を壊さないように拡張します。 In some cases this is better than making a member public when you want to give only one other class access to it. この方法は、クラスのメンバーをある特定のクラスにだけアクセスさせたい場合に、単にそれをpublicにするよりも優れています。 However, most classes should interact with other classes solely through their public members. しかし、ほとんどのクラスはpublicメンバを通してのみ他のクラスとやりとりすべきです。

例外

We do not use C++ exceptions. C++の例外は使いません。

  • Exceptions allow higher levels of an application to decide how to handle "can't happen" failures in deeply nested functions, without the obscuring and error-prone bookkeeping of error codes. 例外の仕組みを用いると、曖昧で取り違えやすいエラーコードの表を使わずに、深くネストされた関数の中で起きた「起こらないはずの」失敗に対する扱い方を、アプリケーションの高レベルの層で決めることができるようになります。
  • Exceptions are used by most other modern languages. 例外は、多くのモダンな言語で取り入れられています。 Using them in C++ would make it more consistent with Python, Java, and the C++ that others are familiar with. C++でそれらを使えば、PythonやJavaやその他のC++に似た言語との一貫性が高くなります。
  • Some third-party C++ libraries use exceptions, and turning them off internally makes it harder to integrate with those libraries. サードパーティのC++ライブラリの中には例外を使っているものもあります。例外を使わないと、それらのライブラリとの統合が難しくなります。
  • Exceptions are the only way for a constructor to fail. 例外はコンストラクタでおきた失敗を伝える唯一の方法です。 We can simulate this with a factory function or an Init() method, but these require heap allocation or a new "invalid" state, respectively. コンストラクタの役割は、ファクトリ関数やInit()メソッドで担うこともできますが、その場合は、ヒープの確保を要したり、「不正」を表す新しい状態を必要としたりします。
  • Exceptions are really handy in testing frameworks. 例外はテストフレームワークにおいては非常に扱いやすいものです。
  • When you add a throw statement to an existing function, you must examine all of its transitive callers. 既に存在している関数にthrow文を加えるときには、その関数の呼び出し元をすべてを確認しなくてはなりません。 Either they must make at least the basic exception safety guarantee, or they must never catch the exception and be happy with the program terminating as a result. それらは、最低限の基本的な例外安全が保証しているか、あるいは、例外を一切キャッチせずに結果的にプログラムを終了させてしまうかのどちらかでしょう。 For instance, if f() calls g() calls h(), and h throws an exception that f catches, g has to be careful or it may not clean up properly. たとえば、f()g()を呼び、g()h()を呼び出していて、hが例外を投げfがキャッチするような場合においては、gを注意深く確かめないと、gの持つリソースが解放されないままになってしまうかもしれません。
  • More generally, exceptions make the control flow of programs difficult to evaluate by looking at code: functions may return in places you don't expect. より一般的には、例外を使用すると、プログラムのコードからコントロールフローを評価するのが難しくなります。 This causes maintainability and debugging difficulties. これは、そのままメンテナンスやデバッグの難しさにつながります。 You can minimize this cost via some rules on how and where exceptions can be used, but at the cost of more that a developer needs to know and understand. 例外の扱い方に関するルールを設けることで、こういったコストは低くすることができるかもしれません。しかし、プログラマがそのルールを知り理解するためにはより多くのコストが掛かってしまいます。
  • Exception safety requires both RAII and different coding practices. 例外安全なプログラムを組むためには、RAIIとそれと異なるコーディングプラクティスとの両方を必要とします。 Lots of supporting machinery is needed to make writing correct exception-safe code easy. 例外安全なコードを正しく簡単に書けるようにするためには、それをサポートするための多くの仕組みが必要となります。 Further, to avoid requiring readers to understand the entire call graph, exception-safe code must isolate logic that writes to persistent state into a "commit" phase. さらに、コードの読者に全体の呼び出しグラフを理解してもらう必要を避けるために、例外安全なコードはmust isolate logic that writes to persistent state into a "commit" phase. This will have both benefits and costs (perhaps where you're forced to obfuscate code to isolate the commit). これには、いい面と悪い面があるでしょう(おそらく、コミットを分離するために、コードをわかりにくくせざるを得なくなります)。 Allowing exceptions would force us to always pay those costs even when they're not worth it. 例外の使用を認めると、たとえ価値が見合わない場合ですら、常にこれらのコストを支払わないといけなくなってしまいます。
  • Turning on exceptions adds data to each binary produced, increasing compile time (probably slightly) and possibly increasing address space pressure. 例外を有効にすると、各バイナリにデータが追加され、(わずかですが)コンパイル時間が延びます。使用できるアドレス空間も減ることになるかもしれません。
  • The availability of exceptions may encourage developers to throw them when they are not appropriate or recover from them when it's not safe to do so. 例外は、それが使えることで、本来適切でないときに例外を投げたり、安全でないにもかかわらず復旧を試みたりするようなことを、開発者に促してしまうかもしれません。 For example, invalid user input should not cause exceptions to be thrown. たとえば、ユーザの入力が不正だった場合には、例外を投げるべきではありません。 We would need to make the style guide even longer to document these restrictions! 例外を認めると、このような制限を書くために、本ガイドをさらに長くしなくてはなりません。

On their face, the benefits of using exceptions outweigh the costs, especially in new projects. 特に新しいプロジェクトの場合は、例外を扱うコストよりも、その恩恵が上回るでしょう。 However, for existing code, the introduction of exceptions has implications on all dependent code. しかし、既存のコードに例外を導入すると、すべての従属するコードに影響を及ぼします。 If exceptions can be propagated beyond a new project, it also becomes problematic to integrate the new project into existing exception-free code. 例外が新しいプロジェクトから波及してくる場合、そのプロジェクトを既存の例外安全なコードに統合するのが難しくなります。 Because most existing C++ code at Google is not prepared to deal with exceptions, it is comparatively difficult to adopt new code that generates exceptions. GoogleのほとんどのC++コードは例外を扱えるように作られていないため、例外を生成する新しいコードに適応するのは非常に難しいことです。

Given that Google's existing code is not exception-tolerant, the costs of using exceptions are somewhat greater than the costs in a new project. Googleの既存のコードは例外を許容できないため、例外を扱うコストは、新規プロジェクトのそれよりも、いくぶん大きいです。 The conversion process would be slow and error-prone. それへの対応は遅く、ミスも起こしやすいでしょう。 We don't believe that the available alternatives to exceptions, such as error codes and assertions, introduce a significant burden. 私たちは、例外の代わりにエラーコードやアサーションといった代替品を使うことが、大きな負担になるとは考えていません。

Our advice against using exceptions is not predicated on philosophical or moral grounds, but practical ones. 我々の例外の使用に対するアドバイスは、哲学的あるいは道徳的背景に基づくものではなく、あくまで実践的なものとしての話です。 Because we'd like to use our open-source projects at Google and it's difficult to do so if those projects use exceptions, we need to advise against exceptions in Google open-source projects as well. 我々は、Googleのオープンソースプロジェクトを使いたいのですが、もしそれらのプロジェクトが例外を使っていたら、そうするのは難しくなってしまいます。そのため、我々はGoogleのオープンソースプロジェクトに対しても、この例外に対するアドバイスをしています。 Things would probably be different if we had to do it all over again from scratch. もし、スクラッチからすべてのことをやり直さなくてはならないのであれば、何かが違っていたかもしれません。

This prohibition also applies to the exception-related features added in C++11, such as noexcept, std::exception_ptr, and std::nested_exception. この禁止はC++11で導入された例外に関連する機能(noexceptstd::exception_ptrstd::nested_exceptionなど)についても同様に適用されます。

There is an exception to this rule (no pun intended) for Windows code. これらのルールにはWindowsのコードに関する例外があります(ダジャレじゃないですよ)。

実行時型情報(RTTI)

Avoid using Run Time Type Information (RTTI). 実行時型情報(RTTI)は使わないでください。

RTTI allows a programmer to query the C++ class of an object at run time. 実行時型情報によって、実行時にオブジェクトの型を調べられるようになります。 This is done by use of typeid or dynamic_cast. これは、typeiddynamic_castを使うことで行われます。

Querying the type of an object at run-time frequently means a design problem. 実行時にオブジェクトの型を調べるのは、大抵の場合、プログラムにデザイン上の問題があることを意味しています。 Needing to know the type of an object at runtime is often an indication that the design of your class hierarchy is flawed. 実行時にオブジェクトの型を知る必要があるということは、クラス階層構造のデザインに欠陥があることを示しています。

Undisciplined use of RTTI makes code hard to maintain. 実行時型情報を雑に扱っていると、コードのメンテナンスが難しくなります。 It can lead to type-based decision trees or switch statements scattered throughout the code, all of which must be examined when making further changes. 実行時型情報を扱うことで、型による分岐やswitch文がコード中に点在してしまうと、将来コードを変更したときに、それらのすべてを試験しなくてはならなくなってしまいます。

The standard alternatives to RTTI (described below) require modification or redesign of the class hierarchy in question. 実行時型情報ではなく、その標準的な代替手段(後述します)を使うと、クラスの階層構造を変更したりデザインしなおしたりする必要があります。 Sometimes such modifications are infeasible or undesirable, particularly in widely-used or mature code. そして、特にそのコードが既に広く使われている場合、そのような変更を施すことは不可能、あるいは望ましくない場合場あります。

RTTI can be useful in some unit tests. 実行時型情報はユニットテストにおいて都合が良い場合があります。 For example, it is useful in tests of factory classes where the test has to verify that a newly created object has the expected dynamic type. たとえば、ファクトリクラスをテストする場合において、生成されたオブジェクトが正しい型であるか確認するためには、実行時型情報は有用です。 It is also useful in managing the relationship between objects and their mocks. また、オブジェクトとそのモックとの関係を管理するのにも便利です。

RTTI is useful when considering multiple abstract objects. 実行時型情報は、多数の抽象オブジェクトを考えるときにも有用です。 Consider 以下の例を見てください。

bool Base::Equal(Base* other) = 0;
bool Derived::Equal(Base* other) {
  Derived* that = dynamic_cast<Derived*>(other);
  if (that == NULL)
    return false;
  ...
}

RTTI has legitimate uses but is prone to abuse, so you must be careful when using it. 実行時型情報には妥当な使い方もあります。ただ、その妥当性から逸脱した使われ方をする傾向もあります。実行時型情報を使うときには十分注意してください。 You may use it freely in unittests, but avoid it when possible in other code. 実行時型情報はユニットテストにおいては自由に使ってもかまいません。それ以外のコードにおいては可能な限り避けてください。 In particular, think twice before using RTTI in new code. 特に、新しいコードで実行時型情報を使おうとする前には、もう一度よく考えてください。 If you find yourself needing to write code that behaves differently based on the class of an object, consider one of the following alternatives to querying the type: もし、オブジェクトの型によって動作が変わるようなコードを書く必要があるとわかったときには、次に示す代替手段を検討してください。

  • Virtual methods are the preferred way of executing different code paths depending on a specific subclass type. 仮想関数を使えば、派生クラスの型によって実行するコードパスを変えることができます。 This puts the work within the object itself. この方法は、分岐する処理をオブジェクト内に書くことができます。
  • If the work belongs outside the object and instead in some processing code, consider a double-dispatch solution, such as the Visitor design pattern. その作業がオブジェクト外に属しており、処理コードも多数ある場合、Visitorパターンのような二重ディスパッチが使えないかを検討してください。 This allows a facility outside the object itself to determine the type of class using the built-in type system. この方法は、オブジェクトの外にある設備が、組み込みの型システムで、型を決定することができます。

When the logic of a program guarantees that a given instance of a base class is in fact an instance of a particular derived class, then a dynamic_cast may be used freely on the object. プログラムの構造的に、ある基底クラスのインスタンスが特定の派生クラスのものであると保証されている場合、dynamic_castを使うことができるでしょう。 Usually one can use a static_cast as an alternative in such situations. 通常、このような場合においては、代替手段としてstatic_castを使うこともできます。

Decision trees based on type are a strong indication that your code is on the wrong track. 型に基づく分岐が出てきたときには、そのコードは間違った方向に進んでいることを強く示しています。

if (typeid(*data) == typeid(D1)) {
  ...
} else if (typeid(*data) == typeid(D2)) {
  ...
} else if (typeid(*data) == typeid(D3)) {
...

Code such as this usually breaks when additional subclasses are added to the class hierarchy. このようなコードは、大抵の場合、クラスの階層構造に新たな派生クラスが増えたときに崩壊してしまいます。 Moreover, when properties of a subclass change, it is difficult to find and modify all the affected code segments. また、派生クラスの性質が変わったときには、その影響があるすべてのコードを検索し、それを変更することも難しいでしょう。

Do not hand-implement an RTTI-like workaround. 実行時型情報のようなものを自前で実装するのもやめてください。 The arguments against RTTI apply just as much to workarounds like class hierarchies with type tags. ここまでしてきた実行時型情報に関する議論は、オブジェクトに型を表すタグをつけるような手法にも同様に当てはまります。 Moreover, workarounds disguise your true intent. その上、このような手法は、あなたの真の意図を隠してしまいます。

キャスト

Use C++-style casts like static_cast<float>(double_value), or brace initialization for conversion of arithmetic types like int64 y = int64{1} << 42. static_cast<float>(double_value)のようなC++スタイルのキャストや、int64 y = int64{1} << 42のような算術型の変換には波括弧による初期化を使ってください。 Do not use cast formats like int y = (int)x or int y = int(x) (but the latter is okay when invoking a constructor of a class type). int y = (int)xint y = int(x)のようなキャストは使わないでください(ただし、クラスのコンストラクタを呼ぶ意図であれば後者はOKです)。

C++ introduced a different cast system from C that distinguishes the types of cast operations. C++には、C言語とは異なり、操作の種類によって区別されるキャストの仕組みが導入されています。

The problem with C casts is the ambiguity of the operation; sometimes you are doing a conversion (e.g., (int)3.5) and sometimes you are doing a cast (e.g., (int)"hello"). C言語のキャストの問題点は、操作が曖昧ということです。ときに変換(例:(int)3.5)であり、ときにキャスト(例:(int)"hello")を表しています。 Brace initialization and C++ casts can often help avoid this ambiguity. 波括弧による初期化とC++のキャストは、この曖昧さを回避するための役に立ちます。 Additionally, C++ casts are more visible when searching for them. 加えて、C++のキャストは検索性も高いです。

The C++-style cast syntax is verbose and cumbersome. C++のキャストは長くて面倒くさいです。

Do not use C-style casts. C言語スタイルのキャストを使わないでください。 Instead, use these C++-style casts when explicit type conversion is necessary. 明示的な型変換が必要な場合は、C言語スタイルのキャストの代わりに、C++スタイルのキャストを使ってください。

  • Use brace initialization to convert arithmetic types (e.g. int64{x}). 算術型の変換には、波括弧による初期化を使用してください(例:int64{x})。 This is the safest approach because code will not compile if conversion can result in information loss. この方法は、型変換によって情報が失われる場合にコンパイルエラーとなるため、最も安全です。 The syntax is also concise. 文法も簡単です。
  • Use static_cast as the equivalent of a C-style cast that does value conversion, when you need to explicitly up-cast a pointer from a class to its superclass, or when you need to explicitly cast a pointer from a superclass to a subclass. あるクラスのポインタを基底クラスのポインタに変換する明示的なアップキャストや、基底クラスのポインタを派生クラスのポインタに明示的にキャストするダウンキャストを行いたい場合には、値の変換を行うC言語スタイルのキャストと等価な、static_castを使用してください。 In this last case, you must be sure your object is actually an instance of the subclass. ダウンキャストを行う場合は、オブジェクトが実際にその派生クラスのインスタンスであることが確信できていないといけません。
  • Use const_cast to remove the const qualifier (see const). const修飾子(constを参照)を外すためにはconst_castを使用してください。
  • Use reinterpret_cast to do unsafe conversions of pointer types to and from integer and other pointer types. ポインタ型と整数型や他の型のポインタ型との間で変換するような、安全でない変換を行う場合はreinterpret_castを使用してください。 Use this only if you know what you are doing and you understand the aliasing issues. ただし、reinterpret_castは、あなたが何をしようとしているのかわかっていて、エイリアシングの問題についても十分理解している場合に限って使用するようにしてください。

See the RTTI section for guidance on the use of dynamic_cast. dynamic_castの扱い方については実行時型情報のセクションも参照してください。

ストリーム

Use streams where appropriate, and stick to "simple" usages. ストリームは、それを使うのが適切な場合に、シンプルな使い方に限定して、使用してください。

Streams are the standard I/O abstraction in C++, as exemplified by the standard header <iostream>. ストリームは、標準ヘッダ<iostream>で例示されるように、C++における標準的な入出力の抽象概念です。 They are widely used in Google code, but only for debug logging and test diagnostics. デバッグログやテスト診断のために限ってですが、Googleのコードでは広く使われています。

The << and >> stream operators provide an API for formatted I/O that is easily learned, portable, reusable, and extensible. ストリーム演算子<<>>はフォーマットされた入出力のためのAPIを提供します。これらは、学びやすく、移植性があり、再利用可能で拡張性もあります。 printf, by contrast, doesn't even support string, to say nothing of user-defined types, and is very difficult to use portably. printfは、それとは対照的に、stringをサポートしませんし、ユーザ定義型もサポートしません。また、移植性の面では非常に難があります。 printf also obliges you to choose among the numerous slightly different versions of that function, and navigate the dozens of conversion specifiers. printfはまた、微妙に異なるたくさんの関数のバージョンがあり、さらに、たくさんの変換指定子があり、それらの中から適切なものを選ばなくてはなりません。

Streams provide first-class support for console I/O via std::cin, std::cout, std::cerr, and std::clog. ストリームは、std::cinstd::coutstd::cerrstd::clogを通して、一級のコンソール入出力サポートを提供します。 The C APIs do as well, but are hampered by the need to manually buffer the input. C言語のAPIでも同様のことができますが、入力は手動でバッファする必要があるため、面倒です。

  • Stream formatting can be configured by mutating the state of the stream. ストリームの書式化はストリームの状態を変更することで設定できます。 Such mutations are persistent, so the behavior of your code can be affected by the entire previous history of the stream, unless you go out of your way to restore it to a known state every time other code might have touched it. この変更は持続するため、ストリームに関するあなたのコードの挙動は、他のコードがストリームに触れるたびに毎回それを既知の状態に戻す独自の方法でも踏まない限り、そこまでのストリーム操作の履歴すべての影響を受けることになります。 User code can not only modify the built-in state, it can add new state variables and behaviors through a registration system. ユーザコードによって、組み込みの状態を変更することはできません。新しい状態変数や動作の追加は、登録の仕組みを通して行えます。
  • It is difficult to precisely control stream output, due to the above issues, the way code and data are mixed in streaming code, and the use of operator overloading (which may select a different overload than you expect). ストリームの出力を正確に制御するのは難しいです。ここまで述べた問題の他、ストリームを扱うコードにおいてはコードとデータが混ざり合ってしまうこと、さらに、演算子のオーバーロードの扱い方も関わっています(意図に反するオーバーロードが選択されてしまうかもしれません)。
  • The practice of building up output through chains of << operators interferes with internationalization, because it bakes word order into the code, and streams' support for localization is flawed . <<演算子による連結によって出力を構築する方法は、国際化対応を妨げます。なぜならば、このやり方は、語順を固定しなくてはならず、ストリームの多言語対応自体にも欠陥があるからです。
  • The streams API is subtle and complex, so programmers must develop experience with it in order to use it effectively. ストリームAPIは繊細で複雑なため、プログラマがそれらを効率的に扱うためにはストリームに関するそれなりの経験を要します。 However, streams were historically banned in Google code (except for logging and diagnostics), so Google engineers tend not to have that experience. しかしながら、Googleのコードにおいては、歴史的にストリームは禁止されていました(ログと診断用のコードを除く)。このため、Googleのエンジニアはストリームにあまり詳しくない傾向があります。 Consequently, streams-based code is likely to be less readable and maintainable by Googlers than code based on more familiar abstractions. したかって、Googleの人間にとっては、他の、より馴染み深い抽象概念に基づいているものと比べて、ストリームの概念に基づくコードは可読性やメンテナンス性が高くありません。
  • Resolving the many overloads of << is extremely costly for the compiler. <<演算子のたくさんのオーバーロードがある中から、それを解決するのは、コンパイラにとって非常にコストの掛かる仕事です。 When used pervasively in a large code base, it can consume as much as 20% of the parsing and semantic analysis time. 大きなコードベースであまねくそれが使われたとき、構文解析と意味解析の時間のうちの20%を消費し得ます。

Use streams only when they are the best tool for the job. ストリームは、その仕事をするために、それが最適なツールとなる場合のみ使用してください。 This is typically the case when the I/O is ad-hoc, local, human-readable, and targeted at other developers rather than end-users. これは、典型的には、エンドユーザではなく、開発者たちのために、アドホックで、局所的で、ヒューマンリーダブルな入出力を行いたいときのことを指します。 Be consistent with the code around you, and with the codebase as a whole; if there's an established tool for your problem, use that tool instead. 周りのコードやコードベース全体と一貫性を持たせてください。もし、この問題に対応するためのツールが既にあるのならば、それを使うようにしてください。

Avoid using streams for I/O that faces external users or handles untrusted data. ストリームを外部のユーザとの入出力のために使用してはいけません。また、ストリームでは信頼できないデータを扱ってはいけません。 Instead, find and use the appropriate templating libraries to handle issues like internationalization, localization, and security hardening. これら場合には、ストリームの代わりに、多言語化の問題に対応し、セキュリティに強固な、より適切なテンプレート化ライブラリを探して、それを使うようにしてください。

If you do use streams, avoid the stateful parts of the streams API (other than error state), such as imbue(), xalloc(), and register_callback(). ストリームを使うことにした場合でも、ストリームAPIのうち、エラー状態を除いて、ステートフルなものは使用しないでください。 たとえば、imbue()xalloc()register_callback()などが当てはまります。 Use explicit formatting functions rather than stream manipulators or formatting flags to control formatting details such as number base, precision, or padding. 基数や精度、出力幅などの制御のためには、マニピュレータやフラグではなく、明示的なフォーマット関数を使用してください。

Overload << as a streaming operator for your type only if your type represents a value, and << writes out a human-readable string representation of that value. 独自の型でストリーム演算子として<<をオーバーロードしてよいのは、 その型が値を表現したものであり、かつ、<<がヒューマンリーダブルな文字列を出力する場合のみに限定してください。 Avoid exposing implementation details in the output of <<; if you need to print object internals for debugging, use named functions instead (a method named DebugString() is the most common convention). <<の出力で、クラスの内部実装を公開してしまわないようにしてください。オブジェクトの内部状態をデバッグのために出力したい場合は、名前をつけた関数を用意してください(慣習的にはDebugString()という名前がもっともよく使われます)。

前置インクリメントと前置デクリメント

Use prefix form (++i) of the increment and decrement operators with iterators and other template objects. イテレータやテンプレートオブジェクトのインクリメントとデクリメント演算子は前置(++i)の形を使用してください。

When a variable is incremented (++i or i++) or decremented (--i or i--) and the value of the expression is not used, one must decide whether to preincrement (decrement) or postincrement (decrement). 変数がインクリメント(++iもしくはi++)あるいはデクリメント(--iもしくはi--)され、かつ、その式の結果が使われないとき、前置インクリメント(デクリメント)を使うか後置インクリメント(デクリメント)を使うかを決めねばなりません。

When the return value is ignored, the "pre" form (++i) is never less efficient than the "post" form (i++), and is often more efficient. 式の結果が無視される場合、「前置」の形(++i)が「後置」(i++)よりも非効率になることはありません。そして大抵は前置のほうが効率的です。 This is because post-increment (or decrement) requires a copy of i to be made, which is the value of the expression. なぜならば、後置の形は、式の値となるiのコピーを作る必要があるためです。 If i is an iterator or other non-scalar type, copying i could be expensive. もし、iが、イテレータやスカラー値でない型の場合、iのコピーは高価になり得ます。 Since the two types of increment behave the same when the value is ignored, why not just always pre-increment? これら2種類のインクリメントは、式の値が無視される場合においてはまったく等価です。だったら、常に前置インクリメントだけを使わない理由が一体全体どこにあるっていうのさ?

The tradition developed, in C, of using post-increment when the expression value is not used, especially in for loops. C言語において、forループなど、式の結果が使われないときは、伝統的に後置が使われていました。 Some find post-increment easier to read, since the "subject" (i) precedes the "verb" (++), just like in English. 後置インクリメントは、英語と同じように、主語(i)の後に述語(++)と続くため、読みやすいと感じる人もいます。

For simple scalar (non-object) values there is no reason to prefer one form and we allow either. 単純なスカラー(オブジェクトでない)の値については、1つの形に絞る理由がないため、どちらの形を使ってもかまいません。 For iterators and other template types, use pre-increment. イテレータやその他の型については、前置を使用してください。

constの使い方

Use const whenever it makes sense. 理にかなっているのならば、常にconstを使ってください。 With C++11, constexpr is a better choice for some uses of const. C++11では、いくつかのconstは、constexprを使うほうがよりよい選択です。

Declared variables and parameters can be preceded by the keyword const to indicate the variables are not changed (e.g., const int foo). 変数や引数の宣言には、その変数が変更されないことを示すために、constキーワードを前置することができます(例:const int foo)。 Class functions can have the const qualifier to indicate the function does not change the state of the class member variables (e.g., class Foo { int Bar(char c) const; }; ). クラスのメンバ関数には、その関数がクラスのメンバ変数の状態を変更しないということを示すために、const修飾子を持つことができます(例:class Foo { int Bar(char c) const; };)。

Easier for people to understand how variables are being used. constは変数の扱われ方に関する理解の助けとなります。 Allows the compiler to do better type checking, and, conceivably, generate better code. constはコンパイラの型チェックを助け、場合によってはよりよいコードを生成できるようにします。 Helps people convince themselves of program correctness because they know the functions they call are limited in how they can modify your variables. 関数にconstがあることで、その関数が変数の変更に対して制限されていることがわかり、それはプログラムの正しさを納得するための助けになります。 Helps people know what functions are safe to use without locks in multi-threaded programs. constは、マルチスレッド下において、どの関数がロックなしで呼び出してもよいかを知る手助けにもなります。

const is viral: if you pass a const variable to a function, that function must have const in its prototype (or the variable will need a const_cast). constは感染します。constな変数を関数に渡すとき、関数はそのプロトタイプでconstを持っていなくてはなりません(あるいは、変数はconst_castされる必要があるでしょう)。 This can be a particular problem when calling library functions. これは、特に、ライブラリ関数を呼び出すときに問題になることもあります。

const variables, data members, methods and arguments add a level of compile-time type checking; it is better to detect errors as soon as possible. constな変数、データメンバ、メンバ関数、引数は、コンパイル時に追加のチェックを行うことができ、これは問題の早期発見のために役立ちます。 Therefore we strongly recommend that you use const whenever it makes sense to do so: このため、次のような場合を含め、適切な場合はいつでもconstを使うのを強く推奨します。

  • If a function guarantees that it will not modify an argument passed by reference or by pointer, the corresponding function parameter should be a reference-to-const (const T&) or pointer-to-const (const T*), respectively. 関数が、参照渡しあるいはポインタ渡しされる引数を変更するつもりがない場合、その引数は、const参照(const T&)かconstポインタ(const T*)でないといけません。
  • Declare methods to be const whenever possible. メンバ関数は、可能な場合は常に、constで宣言します。 Accessors should almost always be const. メンバ変数に対するGetterはほとんど常にconstなはずです。 Other methods should be const if they do not modify any data members, do not call any non-const methods, and do not return a non-const pointer or non-const reference to a data member. その他のメンバ関数は、いずれのデータメンバを変更しない、かつ、constでないメンバ関数を呼ばず、constでないポインタやconstでない参照を返さない場合、constで宣言します。
  • Consider making data members const whenever they do not need to be modified after construction. あるデータメンバがコンストラクタ以外で変更されない場合、常にそのデータメンバをconstとすることを検討してください。

The mutable keyword is allowed but is unsafe when used with threads, so thread safety should be carefully considered first. mutableキーワードも使用が認められていますが、複数のスレッドとともに扱われた場合安全ではなくなります。mutableキーワードをつける前に、スレッドセーフに関して十分検討してください。

constをどこに置くか

Some people favor the form int const *foo to const int* foo. プログラマの中には、const int* fooという形よりint const *fooという形を好む人もいます。 They argue that this is more readable because it's more consistent: it keeps the rule that const always follows the object it's describing. 彼らの主張は「constは常にその特徴付けをするオブジェクトの後に続くというルールを一貫して保てるため、可読性が高い」というものです。 However, this consistency argument doesn't apply in codebases with few deeply-nested pointer expressions since most const expressions have only one const, and it applies to the underlying value. しかしながら、この一貫性に対する主張は、深くネストされたポインタの表現には適用されません。ほとんどのconst表現は、1つのconstのみが書かれ、それはポインタが指し示す値に対して適用されるからです。 In such cases, there's no consistency to maintain. このような場合、もはや一貫性は保たれません。 Putting the const first is arguably more readable, since it follows English in putting the "adjective" (const) before the "noun" (int). constを前置するほうが、おそらく可読性が高まります。これは、英語の文法の「形容詞(const)が名詞(int)の前にくる」と一致しているからです。

That said, while we encourage putting const first, we do not require it. 以上より、我々は、constを先に書くのを推奨しますが、これを必須のルールとはしません。 But be consistent with the code around you! ただし、周囲のコードとの一貫性は保つようにしてください。

constexprの使い方

In C++11, use constexpr to define true constants or to ensure constant initialization. C++11では、真の定数を定義するときや、定数初期化を保証するときに、constexprを使用してください。

Some variables can be declared constexpr to indicate the variables are true constants, i.e. fixed at compilation/link time. 変数をconstexprとして宣言することで、それが真の定数(コンパイル時かリンク時に決定)されることを示すことができます。 Some functions and constructors can be declared constexpr which enables them to be used in defining a constexpr variable. また、関数やコンストラクタをはconstexprとして宣言することで、それをconstexpr変数の定義のために使えるようにすることができます。

Use of constexpr enables definition of constants with floating-point expressions rather than just literals; definition of constants of user-defined types; and definition of constants with function calls. constexprを使うことで、ただのリテラルではない浮動小数点式を定数として宣言できるようになります。また、constexprによって、ユーザ定義の型を定数として宣言したり、関数呼び出しの結果を定数として定義することができるようになります。

Prematurely marking something as constexpr may cause migration problems if later on it has to be downgraded. 早まって何かをconstexprで宣言してしまうと、後でダウングレードする必要がでてきた場合、マイグレーション時の問題となるかもしれません。 Current restrictions on what is allowed in constexpr functions and constructors may invite obscure workarounds in these definitions. 現時点では、関数やコンストラクタにconstexprをつけることが認められていますが、それによってそれらの定義に、まだあまり知られていない手法を引き込んでしまうかもしれません。

constexpr definitions enable a more robust specification of the constant parts of an interface. constexprによって、インターフェースの定数に関する部分を、より堅牢なものにできます。 Use constexpr to specify true constants and the functions that support their definitions. 真の定数を決めるときや、関数が真の定数の定義をサポートするときは、constexprを使用してください。 Avoid complexifying function definitions to enable their use with constexpr. ただし、constexprを使いたいがためだけに、関数定義を複雑化させるのは避けてください。 Do not use constexpr to force inlining. また、インライン化を強制する目的ではconstexprを使用してはいけません。

整数型

Of the built-in C++ integer types, the only one used is int. C++における組み込みの整数型の中で、最も使われているのはintです。 If a program needs a variable of a different size, use a precise-width integer type from <stdint.h>, such as int16_t. プログラムが異なるサイズの変数を必要とするときは、<stdint.h>から、int16_tのような、サイズが明示された整数型を使うようにしてください。 If your variable represents a value that could ever be greater than or equal to 2^31 (2GiB), use a 64-bit type such as int64_t. 変数が、2^31 (2GiB)以上の値を示すかもしれない場合、int64_tのような64ビットの型を使ってください。 Keep in mind that even if your value won't ever be too large for an int, it may be used in intermediate calculations which may require a larger type. また、変数がintの範囲を超えることがないとわかっている場合でも、その中間の計算において、より大きな型が必要とされることもあるため、そのことを常に念頭に置くようにしてください。 When in doubt, choose a larger type. 迷ったときには大きな型を選んでください。

C++ does not specify the sizes of its integer types. C++において、整数型のサイズは仕様として決められていません。 Typically people assume that short is 16 bits, int is 32 bits, long is 32 bits and long long is 64 bits. 多くの場合、shortが16ビット、intが32ビット、longが32ビット、long longは64ビットであると仮定されています。

Uniformity of declaration. 宣言が画一的です。

The sizes of integral types in C++ can vary based on compiler and architecture. C++における整数型のサイズは、そのコンパイラやアーキテクチャに基づいて異なります。

<stdint.h> defines types like int16_t, uint32_t, int64_t, etc. <stdint.h>は、int16_tuint32_tint64_tなどのような型を定義しています。 You should always use those in preference to short, unsigned long long and the like, when you need a guarantee on the size of an integer. 整数型のサイズを保証する必要がある場合は、shortunsigned long long等ではなく、常にint16_tuint64_tを優先して使ってください。 Of the C integer types, only int should be used. C言語の整数型は、intのみが使用できます。 When appropriate, you are welcome to use standard types like size_t and ptrdiff_t. また、それが適切な場合は、size_tptrdiff_tなどの標準の型を使用してもかまいません。

We use int very often, for integers we know are not going to be too big, e.g., loop counters. たとえばループカウンタなど、そんなに大きくならないとわかっている整数について、intは非常によく使われます。 Use plain old int for such things. このような場合は、Plain Old なintを使ってください。 You should assume that an int is at least 32 bits, but don't assume that it has more than 32 bits. intは最低でも32ビットあると仮定して構いません。 ただし、32ビットよりも大きいという仮定を行ってはいけません。 If you need a 64-bit integer type, use int64_t or uint64_t. もし64ビットの整数型を必要とする場合は、int64_tuint64_tを使ってください。

For integers we know can be "big", use int64_t. 大きくなるかもしれないことがわかっている整数については、int64_tを使ってください。

You should not use the unsigned integer types such as uint32_t, unless there is a valid reason such as representing a bit pattern rather than a number, or you need defined overflow modulo 2^N. uint32_t等のunsignedな整数型は、明確な理由がない限り使用すべきではありません。たとえば、変数が数値ではなくビットパターンを表している場合や、意図的にオーバーフローさせて2^Nによる剰余がほしい場合などが当てはまります。 In particular, do not use unsigned types to say a number will never be negative. 特に、整数が絶対に負にならないということを表す目的ではunsigned型を使ってはいけません。 Instead, use assertions for this. そのような目的には、assertionを使用してください。

If your code is a container that returns a size, be sure to use a type that will accommodate any possible usage of your container. もしあなたがコンテナを作っているところで、そのサイズを返そうとしている場合には、そのコンテナがどのように扱われても対応できるであろう型を選んでください。 When in doubt, use a larger type rather than a smaller type. 迷ったら、小さな型よりも大きな型を使いましょう。

Use care when converting integer types. 整数型の変換には注意してください。 Integer conversions and promotions can cause non-intuitive behavior. 整数型の変換や型の拡張は、ときに直感に反する挙動を示す場合があります。

unsignedな整数

Some people, including some textbook authors, recommend using unsigned types to represent numbers that are never negative. 著名な本の著者も含めて、プログラマの中には、絶対に負の値をとらない変数にはunsignedな型を使うのを推奨する人もいます。 This is intended as a form of self-documentation. これは、それ自体がドキュメントの働きをすることを狙ったものです。 However, in C, the advantages of such documentation are outweighed by the real bugs it can introduce. しかし、C言語においては、このようなドキュメント化のメリットよりも、現実のバグを引き込むリスクの方が高いです。 Consider: 次のコードを考えてみてください。

for (unsigned int i = foo.Length()-1; i >= 0; --i) ...

This code will never terminate! そう、無限ループです。 Sometimes gcc will notice this bug and warn you, but often it will not. GCCはこのようなバグに気づいて警告してくれることもありますが、してくれないことも多いです。 Equally bad bugs can occur when comparing signed and unsigned variables. 同様の残念なバグは、signed変数とunsigned変数との比較でも発生し得ます。 Basically, C's type-promotion scheme causes unsigned types to behave differently than one might expect. 基本的に、C言語の型の拡張のスキームは、unsigned型に対して期待していたものとは異なる動作を引き起こします。

So, document that a variable is non-negative using assertions. 変数が負にならないことをドキュメント化するためには、assertionを使ってください。 Don't use an unsigned type. unsigned型は使ってはいけません。

64ビットへの移植性

Code should be 64-bit and 32-bit friendly. コードは64ビットと32ビットの両方にフレンドリーであるべきです。 Bear in mind problems of printing, comparisons, and structure alignment. printするとき、比較するとき、構造体のアラインメントの問題を常に心にとめておいてください。

  • printf() specifiers for some types are not cleanly portable between 32-bit and 64-bit systems. printf()の仕様は、32ビットシステムと64ビットシステムの間で、きれいに互換がとれていません。 C99 defines some portable format specifiers. C99で、移植性のあるいくつか書式指定子の定義が行われました。 Unfortunately, MSVC 7.1 does not understand some of these specifiers and the standard is missing a few, so we have to define our own ugly versions in some cases (in the style of the standard include file inttypes.h): しかし、MSVC 7.1はそれらの仕様を理解せず、標準的なものもいくつか欠けています。そこで、我々は、以下に示すような、独自の醜いバージョンを定義する必要がありました(標準インクルードファイルであるinttypes.hと同じスタイル):。

    // printf macros for size_t, in the style of inttypes.h
    #ifdef _LP64
    #define __PRIS_PREFIX "z"
    #else
    #define __PRIS_PREFIX
    #endif
    
    // Use these macros after a % in a printf format string
    // to get correct 32/64 bit behavior, like this:
    // size_t size = records.size();
    // printf("%" PRIuS "\n", size);
    
    #define PRIdS __PRIS_PREFIX "d"
    #define PRIxS __PRIS_PREFIX "x"
    #define PRIuS __PRIS_PREFIX "u"
    #define PRIXS __PRIS_PREFIX "X"
    #define PRIoS __PRIS_PREFIX "o"
      
    // size_t の printf 用マクロ
    #ifdef _LP64
    #define __PRIS_PREFIX "z"
    #else
    #define __PRIS_PREFIX
    #endif
    
    // これらのマクロを、printfの書式指定文字列の中の%の後ろで使うことで、
    // 32ビットと64ビットで正しい挙動が得られる。
    // 例: 
    //   size_t size = records.size();
    //   printf("%" PRIuS "\n", size);
    
    #define PRIdS __PRIS_PREFIX "d"
    #define PRIxS __PRIS_PREFIX "x"
    #define PRIuS __PRIS_PREFIX "u"
    #define PRIXS __PRIS_PREFIX "X"
    #define PRIoS __PRIS_PREFIX "o"
      
    使わない 使う 備考
    void * (or any pointer) %lx %p
    int64_t %qd, %lld %" PRId64 "
    uint64_t %qu, %llu, %llx %" PRIu64 ", %" PRIx64 "
    size_t %u %" PRIuS ", %" PRIxS " C99の仕様では %zu
    ptrdiff_t %d %" PRIdS " C99の仕様では %td

    Note that the PRI* macros expand to independent strings which are concatenated by the compiler. PRI*マクロは、独立した文字列に展開され、コンパイラにより連結されます。 Hence if you are using a non-constant format string, you need to insert the value of the macro into the format, rather than the name. ゆえに、書式指定文字列にリテラルを使っていない場合は、マクロの名前ではなく、マクロを展開した値を挿入する必要があります。 Note also that spaces are required around the macro identifier to separate it from the string literal. また、マクロの識別子の前後には、文字列リテラルと分離するためのスペースが必要なことも注意してください。 It is still possible, as usual, to include length specifiers, etc., after the % when using the PRI* macros. これらを使う場合でも、普段通り、幅指定子などを含めることができます。%の後ろに、PRI*を使う前に挿入します。 So, e.g. printf("x = %30" PRIuS "\n", x) would expand on 32-bit Linux to printf("x = %30" "u" "\n", x) , which the compiler will treat as printf("x = %30u\n", x). たとえば、 printf("x = %30" PRIuS "\n", x)は、32ビットのLinuxでは、printf("x = %30" "u" "\n", x)と展開され、コンパイラはこれをprintf("x = %30u\n", x)として扱うでしょう。

  • Remember that sizeof(void *) != sizeof(int). sizeof(void *) != sizeof(int)であることを忘れないでください。 Use intptr_t if you want a pointer-sized integer. ポインタと同じサイズの整数が必要なときは、intptr_tを使ってください。
  • You may need to be careful with structure alignments, particularly for structures being stored on disk. 構造体のアラインメントに注意を払う必要があります(特に、構造体がディスクに保存される場合)。 Any class/structure with a int64_t/uint64_t member will by default end up being 8-byte aligned on a 64-bit system. 64ビットシステムにおいて、int64_tuint64_tを含むクラスや構造体は、デフォルトでは8バイト境界にアラインメントされます。 If you have such structures being shared on disk between 32-bit and 64-bit code, you will need to ensure that they are packed the same on both architectures. もし、このような構造体をディスクに保存して32ビットのコードと64ビットのコードで共有する場合、両方のアーキテクチャで同じようにパックされることを保証する必要があるでしょう。 Most compilers offer a way to alter structure alignment. ほとんどのコンパイラは、構造体のアラインメントを変える手段を提供しています。 For gcc, you can use __attribute__((packed)). GCCでは、__attribute__((packed))が使えます。 MSVC offers #pragma pack() and __declspec(align()). MSVCは#pragma pack()__declspec(align())を提供しています。
  • Use the LL or ULL suffixes as needed to create 64-bit constants. 64ビット定数を作るためには、LLULLといった接頭辞を使ってください。 For example: 例を挙げます。

    int64_t my_value = 0x123456789LL;
    uint64_t my_mask = 3ULL << 48;
    

プリプロセッサマクロ

Avoid defining macros, especially in headers; prefer inline functions, enums, and const variables. マクロを定義してはいけません(特にヘッダでは)。 インライン関数や、列挙型、const変数を使いましょう。 Name macros with a project-specific prefix. マクロの名前にはプロジェクト固有の接頭辞をつけてください。 Do not use macros to define pieces of a C++ API. C++ APIを定義するために、マクロを使わないでください。

Macros mean that the code you see is not the same as the code the compiler sees. マクロによって、あなたが見ているコードとコンパイラから見たコードが同じではなくなります。 This can introduce unexpected behavior, especially since macros have global scope. これによって、特に、マクロがグローバルスコープのとき、意図しない挙動を引き起こすことがあります。

The problems introduced by macros are especially severe when they are used to define pieces of a C++ API, and still more so for public APIs. マクロによって引き起こされる問題は、特に、マクロがC++APIとして、特にpublicなAPIとして定義されたときに重大です。 Every error message from the compiler when developers incorrectly use that interface now must explain how the macros formed the interface. 開発者がインターフェースの使い方を間違えたときのコンパイラからのエラーメッセージは、マクロがどのようにインターフェースを形成しているかを説明しなくてはなりません。 Refactoring and analysis tools have a dramatically harder time updating the interface. リファクタリングや解析のツールはインターフェースを更新するために劇的な時間が掛かるようになります。 As a consequence, we specifically disallow using macros in this way. 以上のことより、我々は明確に、マクロをこの方法で使用することを禁止します。 For example, avoid patterns like: たとえば、避けるべきパターンは次の通りです。

class WOMBAT_TYPE(Foo) {
  // ...

 public:
  EXPAND_PUBLIC_WOMBAT_API(Foo)

  EXPAND_WOMBAT_COMPARISONS(Foo, ==, <)
};

Luckily, macros are not nearly as necessary in C++ as they are in C. 幸いにも、C++はC言語ほどマクロを必要としません。 Instead of using a macro to inline performance-critical code, use an inline function. パフォーマンスクリティカルなコードをインライン化する時には、マクロではなくインライン関数を使ってください。 Instead of using a macro to store a constant, use a const variable. 定数を保存するためには、マクロではなくconst変数を使ってください。 Instead of using a macro to "abbreviate" a long variable name, use a reference. 長い名前の変数の短縮形を作るためには、マクロではなく参照を使ってください。 Instead of using a macro to conditionally compile code ... well, don't do that at all (except, of course, for the #define guards to prevent double inclusion of header files). 状況によってコンパイルされるコードを変えるためには、マクロではなく……いや、そもそもそんなことをしてはいけません(もちろん、多重インクルードを防ぐためのインクルードガードは例外です)。 It makes testing much more difficult. そのようなことをすると、テストが非常に難しくなります。

Macros can do things these other techniques cannot, and you do see them in the codebase, especially in the lower-level libraries. マクロは他の方法ではできないことを実現できるため、既存のコードベースにおいて、特に低レベルなライブラリでそれらを見かけることがあるかもしれません。 And some of their special features (like stringifying, concatenation, and so forth) are not available through the language proper. さらに、マクロには、文字列化や連結など特別な機能があり、それらの機能は言語では提供されません。 But before using a macro, consider carefully whether there's a non-macro way to achieve the same result. ただし、マクロを使う前に、マクロではない方法で同じ結果を達成する方法がないかよく検討してください。 If you need to use a macro to define an interface, contact your project leads to request a waiver of this rule. もし、マクロを使ってインターフェースを定義する必要が生じた場合は、このルールを破棄するために、プロジェクトリーダーと相談してください。

The following usage pattern will avoid many problems with macros; if you use macros, follow it whenever possible: 以下に示すようなマクロの使い方をすれば、多くの問題を避けることができます。マクロを定義しようとするときは可能な限りこれらに従ってください。

  • Don't define macros in a .h file. .hファイルでは、マクロを定義してはいけません。
  • #define macros right before you use them, and #undef them right after. マクロは使う直前に#defineし、使い終わったらすぐに#undefしてください。
  • Do not just #undef an existing macro before replacing it with your own; instead, pick a name that's likely to be unique. 既存のマクロを自分のものに置き換えるために、#undefしてはいけません。 代わりに、あなたのマクロにユニークとなる前をつけてください。
  • Try not to use macros that expand to unbalanced C++ constructs, or at least document that behavior well. C++の偏った構造を拡張するためにマクロを使おうとしないでください。あるいは、少なくとも、その挙動について十分なドキュメント化を行ってください。
  • Prefer not using ## to generate function/class/variable names. 関数名やクラス名、変数名を生成するために##を使うのはやめましょう。

Exporting macros from headers (i.e. defining them in a header without #undefing them before the end of the header) is extremely strongly discouraged. ヘッダからマクロをエクスポートする(言い換えると、ヘッダでマクロを定義し、そのヘッダの終わりまで#undefしない)ことは、非常に強く非推奨です。 If you do export a macro from a header, it must have a globally unique name. もし、そのようなマクロをヘッダからエクスポートする場合は、グローバルにユニークな名前でなくてはなりません。 To achieve this, it must be named with a prefix consisting of your project's namespace name (but upper case). そのため、必ずプロジェクトのnamespaceの名前を(すべて大文字で)マクロ名の頭につけるようにしてください。

0とnullptrとNULL

Use 0 for integers, 0.0 for reals, nullptr (or NULL) for pointers, and '\0' for chars. 整数には0、実数には0.0、ポインタにはnullptr(か、NULL)、文字には'\0'を使ってください。

Use 0 for integers and 0.0 for reals. 整数には0、実数には0.0を使ってください。 This is not controversial. ここに議論の余地はありません。

For pointers (address values), there is a choice between 0, NULL, and nullptr. ポインタ(やアドレス)には、0NULLnullptrかという選択があります。 For projects that allow C++11 features, use nullptr. C++11が使えるプロジェクトにおいては、nullptrを使ってください。 For C++03 projects, we prefer NULL because it looks like a pointer. C++03のプロジェクトでは、見た目にポインタとわかるようにするため、NULLを使いましょう。 In fact, some C++ compilers provide special definitions of NULL which enable them to give useful warnings, particularly in situations where sizeof(NULL) is not equal to sizeof(0). 実際には、いくつかのC++コンパイラは、NULLの特別な定義を提供しており、特に、sizeof(NULL)sizeof(0)とが一致しない場合などにおいて、有用な警告を発してくれます。

Use '\0' for chars. 文字には'\0'を使います。 This is the correct type and also makes code more readable. これは、正しい型であり、かつ可読性も向上します。

sizeof

Prefer sizeof(varname) to sizeof(type). sizeof()よりもsizeof(変数名)を使いましょう。

Use sizeof(varname) when you take the size of a particular variable. 具体的な変数のサイズを知りたいときにはsizeof(変数名)を使ってください。 sizeof(varname) will update appropriately if someone changes the variable type either now or later. sizeof(変数名)であれば、変数の型に変更があった場合でも適切に追従してくれます。 You may use sizeof(type) for code unrelated to any particular variable, such as code that manages an external or internal data format where a variable of an appropriate C++ type is not convenient. 具体的な変数に結びつかない場合はsizeof()を使ってもかまいません。たとえば、外部や内部のデータのフォーマットを管理したい場合で、かつC++の型の仕組みが不十分な場合などです。

Struct data;
memset(&data, 0, sizeof(data));
memset(&data, 0, sizeof(Struct));
memset(&data, 0, sizeof(Struct));  // これは避ける
if (raw_size < sizeof(int)) {
  LOG(ERROR) << "compressed record not big enough for count: " << raw_size;
  return false;
}

auto

Use auto to avoid type names that are noisy, obvious, or unimportant - cases where the type doesn't aid in clarity for the reader. 型の名前が騒がしい場合や、明確な場合、重要でない場合(=型の名前が読者の理解の役に立たない場合)はautoを使ってください。 Continue to use manifest type declarations when it helps readability. 型名を明示することで可読性が向上する場合は、従来通り、型の名前を明示して宣言を行ってください。

  • C++ type names can be long and cumbersome, especially when they involve templates or namespaces. C++の型名は、特にテンプレートや名前空間を含んだ場合、長く面倒なものになりがちです。
  • When a C++ type name is repeated within a single declaration or a small code region, the repetition may not be aiding readability. 1つの宣言や小さなコードブロックの中で、C++の型名の繰り返されることは、可読性の助けにはなりません。
  • It is sometimes safer to let the type be specified by the type of the initialization expression, since that avoids the possibility of unintended copies or type conversions. また、意図しないコピーや型変換を避けるために、変数の型を初期化式の型で決定するほうがより安全な場合もあります。

Sometimes code is clearer when types are manifest, especially when a variable's initialization depends on things that were declared far away. 型が明示された方がコードがわかりやすくなる場合があります。特に、初期化子が離れたところで宣言されたものに依存している場合などです。 In expressions like: たとえば次のような式を考えてみます。

auto foo = x.add_foo();
auto i = y.Find(key);

it may not be obvious what the resulting types are if the type of y isn't very well known, or if y was declared many lines earlier. この式において、yの型が十分に知られていなかったり、yがずっと前に宣言されていたりした場合、式の結果の型が明確であるとはいえないでしょう。

Programmers have to understand the difference between auto and const auto& or they'll get copies when they didn't mean to. プログラマはautoconst auto&の違いについて理解していなければなりません。さもなくば、意図せずオブジェクトのコピーを得ることになってしまうかもしれません。

If an auto variable is used as part of an interface, e.g. as a constant in a header, then a programmer might change its type while only intending to change its value, leading to a more radical API change than intended. auto変数が、インターフェースの一部(ヘッダにおける定数など)として使われていた場合、プログラマはその値を変えるだけのつもりで、型も変えてしまうかもしれません。これによって意図した変更よりも根本的なAPIの変更を招いてしまうかもしれません。

auto is permitted when it increases readability, particularly as described below. autoは、特に次に述べるような、可読性を向上させる場合にのみ使うことができます。 Never initialize an auto-typed variable with a braced initializer list. auto変数を初期化子リストで初期化してはいけません。

Specific cases where auto is allowed or encouraged: autoが認められる、または推奨されるのは次のような場合です。

  • (Encouraged) For iterators and other long/cluttery type names, particularly when the type is clear from context (calls to find, begin, or end for instance). (推奨) イテレータやそのほかの長い型名、特にfindbeginendの呼び出し時など、型が文脈から明らかにわかる場合。
  • (Allowed) When the type is clear from local context (in the same expression or within a few lines). (許可) 局所的な文脈(同じ式の中か、1~2行の範囲内)から型が明らかなとき。 Initialization of a pointer or smart pointer with calls to new commonly falls into this category, as does use of auto in a range-based loop over a container whose type is spelled out nearby. newを伴うポインタやスマートポインタの初期化がこのカテゴリに属します。また、近くに型が書かれているコンテナに対する、レンジベースのループのautoも同様です。
  • (Allowed) When the type doesn't matter because it isn't being used for anything other than equality comparison. (許可) 型が重要でないとき。等価比較以外の目的で使われていない場合など。
  • (Encouraged) When iterating over a map with a range-based loop (because it is often assumed that the correct type is std::pair<KeyType, ValueType> whereas it is actually std::pair<const KeyType, ValueType>). (推奨) レンジベースのループでmapをイテレートする場合のイテレータ。(このイテレータの本当の型はstd::pair<const KeyType, ValueType>であるにも関わらず、型がstd::pair<KeyType, ValueType>であると誤認されるため)。 This is particularly well paired with local key and value aliases for .first and .second (often const-ref). これは特に、局所変数keyvalue.first.secondへの別名として定義される場合とセットの場合に言えます。
    for (const auto& item : some_map) {
      const KeyType& key = item.first;
      const ValType& value = item.second;
      // The rest of the loop can now just refer to key and value,
      // a reader can see the types in question, and we've avoided
      // the too-common case of extra copies in this iteration.
    }
    
    for (const auto& item : some_map) {
      const KeyType& key = item.first;
      const ValType& value = item.second;
      // ループの残りの部分では key と value を参照します。
      // コードの読み手は対象の型を見ることができ、
      // 書き手はこのイテレーションにおいてよくあるコピーの問題を回避できています。
    }
    

波括弧による初期化子リスト

You may use braced initializer lists. 波括弧による初期化リストを使ってもよいです。

In C++03, aggregate types (arrays and structs with no constructor) could be initialized with braced initializer lists. C++03では、aggregateな型(配列や、コンストラクタを持たない構造体)が、波括弧による初期化子リストで初期化できました。

struct Point { int x; int y; };
Point p = {1, 2};

In C++11, this syntax was generalized, and any object type can now be created with a braced initializer list, known as a braced-init-list in the C++ grammar. C++11では、この文法はより一般化され、C++の文法における初期化子リストとして知られているように、どのようなオブジェクトもこの波括弧で囲まれた初期化子のリストで初期化できるようになりました。 Here are a few examples of its use. それらの使用例を以下に示します。

// Vector takes a braced-init-list of elements.
std::vector<string> v{"foo", "bar"};

// Basically the same, ignoring some small technicalities.
// You may choose to use either form.
std::vector<string> v = {"foo", "bar"};

// Usable with 'new' expressions.
auto p = new vector<string>{"foo", "bar"};

// A map can take a list of pairs. Nested braced-init-lists work.
std::map<int, string> m = {{1, "one"}, {2, "2"}};

// A braced-init-list can be implicitly converted to a return type.
std::vector<int> test_function() { return {1, 2, 3}; }

// Iterate over a braced-init-list.
for (int i : {-1, -2, -3}) {}

// Call a function using a braced-init-list.
void TestFunction2(std::vector<int> v) {}
TestFunction2({1, 2, 3});
// vector はその要素となる初期化子リストをとります。.
std::vector<string> v{"foo", "bar"};

// 細則を無視すれば、上記と基本的には同じです。
// どちらの形を使用してもかまいません。
std::vector<string> v = {"foo", "bar"};

// newとともに使うこともできます。
auto p = new vector<string>{"foo", "bar"};

// mapは、ペアのリストをとります。初期化子リストはネストすることができます。
std::map<int, string> m = {{1, "one"}, {2, "2"}};

// 初期化子リストは戻り値の型に暗黙的に変換されます。
std::vector<int> test_function() { return {1, 2, 3}; }

// 初期化子リストをイテレートすることもできます。
for (int i : {-1, -2, -3}) {}

// 初期化子リストを用いて関数を呼ぶこともできます。
void TestFunction2(std::vector<int> v) {}
TestFunction2({1, 2, 3});

A user-defined type can also define a constructor and/or assignment operator that take std::initializer_list<T>, which is automatically created from braced-init-list: ユーザ定義の型は、std::initializer_list<T>を引数にとるコンストラクタや代入演算子を定義することで、初期化子リストからオブジェクトを生成することができます。以下に例を示します。

class MyType {
 public:
  // std::initializer_list references the underlying init list.
  // It should be passed by value.
  MyType(std::initializer_list<int> init_list) {
    for (int i : init_list) append(i);
  }
  MyType& operator=(std::initializer_list<int> init_list) {
    clear();
    for (int i : init_list) append(i);
  }
};
MyType m{2, 3, 5, 7};
class MyType {
 public:
  // std::initializer_list は、渡された初期化子リストを参照します。
  // これは値渡しになります。
  MyType(std::initializer_list<int> init_list) {
    for (int i : init_list) append(i);
  }
  MyType& operator=(std::initializer_list<int> init_list) {
    clear();
    for (int i : init_list) append(i);
  }
};
MyType m{2, 3, 5, 7};

Finally, brace initialization can also call ordinary constructors of data types, even if they do not have std::initializer_list<T> constructors. 最後になりますが、初期化子リストは、std::initializer_list<T>のコンストラクタを持たないふつうのデータ型のコンストラクタを呼ぶこともできます。

double d{1.23};
// Calls ordinary constructor as long as MyOtherType has no
// std::initializer_list constructor.
class MyOtherType {
 public:
  explicit MyOtherType(string);
  MyOtherType(int, string);
};
MyOtherType m = {1, "b"};
// If the constructor is explicit, you can't use the "= {}" form.
MyOtherType m{"b"};
double d{1.23};
// MyOtherTypeはstd::initializer_listのコンストラクタを持っていないため、
// 通常のコンストラクタが呼び出されます。
class MyOtherType {
 public:
  explicit MyOtherType(string);
  MyOtherType(int, string);
};
MyOtherType m = {1, "b"};
// もし、コンストラクタがexplicitでマークされていた場合、
// 「= {}」の形を使用することはできません。
MyOtherType m{"b"};

Never assign a braced-init-list to an auto local variable. 初期化子リストでautoなローカル変数を割り当ててはいけません。 In the single element case, what this means can be confusing. 要素が1つの場合、その意味がわかりません。

auto d = {1.23};        // d is a std::initializer_list<double>
auto d = {1.23};        // d は std::initializer_list<double>
auto d = double{1.23};  // Good -- d is a double, not a std::initializer_list.
auto d = double{1.23};  // これはOK。dはdouble。std::initializer_listにはなりません。

See Braced_Initializer_List_Format for formatting. フォーマットについては波括弧による初期化子リストも参照してください。

ラムダ式

Use lambda expressions where appropriate. ラムダ式は、それが適切な場合に、使用してください。 Prefer explicit captures when the lambda will escape the current scope. ラムダ式が現在のスコープの外に出て行くときは、明示的に変数をキャプチャしましょう。

Lambda expressions are a concise way of creating anonymous function objects. ラムダ式は、匿名関数オブジェクトを作るための簡潔な方法です。 They're often useful when passing functions as arguments. For example: ラムダ式は、関数の引数として渡す場合にも便利です。例を見てみましょう。

std::sort(v.begin(), v.end(), [](int x, int y) {
  return Weight(x) < Weight(y);
});

They further allow capturing variables from the enclosing scope either explicitly by name, or implicitly using a default capture. ラムダ式は、自身を囲むスコープから変数をキャプチャすることができます。変数をキャプチャは、明示的に名前を指定するか、暗黙的なデフォルトのキャプチャを使うかのどちらかによって行われます。 Explicit captures require each variable to be listed, as either a value or reference capture: 明示的なキャプチャのためには、次のように、各変数を、値とするか参照とするかを指定しつつリストに並べます。

int weight = 3;
int sum = 0;
// Captures `weight` by value and `sum` by reference.
std::for_each(v.begin(), v.end(), [weight, &sum](int x) {
  sum += weight * x;
});
int weight = 3;
int sum = 0;
// weigthは値として、sumは参照としてキャプチャしています。
std::for_each(v.begin(), v.end(), [weight, &sum](int x) {
  sum += weight * x;
});
Default captures implicitly capture any variable referenced in the lambda body, including this if any members are used: デフォルトのキャプチャは暗黙的にラムダ式の本体で参照されたすべての変数をキャプチャします。何らかのメンバが使われている場合はthisもキャプチャされます。
const std::vector<int> lookup_table = ...;
std::vector<int> indices = ...;
// Captures `lookup_table` by reference, sorts `indices` by the value
// of the associated element in `lookup_table`.
std::sort(indices.begin(), indices.end(), [&](int a, int b) {
  return lookup_table[a] < lookup_table[b];
});
const std::vector<int> lookup_table = ...;
std::vector<int> indices = ...;
// lookup_tableを参照としてキャプチャし、
// lookup_tableの要素に関連づけられたindicesの値をソートしています。
std::sort(indices.begin(), indices.end(), [&](int a, int b) {
  return lookup_table[a] < lookup_table[b];
});

Lambdas were introduced in C++11 along with a set of utilities for working with function objects, such as the polymorphic wrapper std::function. ラムダ式は、関数オブジェクトとともに動作するユーティリティ一式(たとえば、std::functionなど)とともにC++11で導入されました。

  • Lambdas are much more concise than other ways of defining function objects to be passed to STL algorithms, which can be a readability improvement. ラムダ式は、STLのアルゴリズムに渡すためには、関数オブジェクトを作るよりも遙かに簡潔な方法であり、可読性も向上させます。
  • Appropriate use of default captures can remove redundancy and highlight important exceptions from the default. デフォルトキャプチャを適切に用いることで、余分な記述を減らせます。また、デフォルトとは異なる重要な例外を目立たせることもできます。
  • Lambdas, std::function, and std::bind can be used in combination as a general purpose callback mechanism; they make it easy to write functions that take bound functions as arguments. ラムダ式やstd::functionstd::bindは、一般的なコールバックのメカニズムにとして組み合わせて使用することができます。これらを使うことで、引数に動作を示す関数をとるような関数が書きやすくなります。
  • Variable capture in lambdas can be a source of dangling-pointer bugs, particularly if a lambda escapes the current scope. ラムダ式の変数のキャプチャは、ダングリングポインタバグの元になる危険があり、特にラムダ式がそのスコープの外に出ていくときは注意が必要です。
  • Default captures by value can be misleading because they do not prevent dangling-pointer bugs. デフォルトでは値によるキャプチャが行われますが、これらがダングリングポインタのバグを防ぐことはないため、ミスリードも起こしやすいです。 Capturing a pointer by value doesn't cause a deep copy, so it often has the same lifetime issues as capture by reference. ポインタを値でキャプチャしてもそれが自動的にディープコピーされることはありません。このため、参照でキャプチャした場合と同様に、オブジェクトの生存期間に関する問題をはらみます。 This is especially confusing when capturing 'this' by value, since the use of 'this' is often implicit. 特に、thisポインタを値でキャプチャした場合には混乱の元になりやすいです。thisは暗黙的に使用されることが多いからです。
  • It's possible for use of lambdas to get out of hand; very long nested anonymous functions can make code harder to understand. ラムダ式は、手に余るような扱い方もできてしまいます。たとえば、非常に長い匿名の関数がネストされているような状況では、そのコードを理解するのは難しいでしょう。
  • Use lambda expressions where appropriate, with formatting as described below. ラムダ式は、適切な場合に限り、使用してください。その際の書式はラムダ式の書式に従ってください。
  • Prefer explicit captures if the lambda may escape the current scope. ラムダ式が現在のスコープの外に出て行く場合は、明示的なキャプチャを使いましょう。 For example, instead of: 以下に例を示します。悪い例から。
    {
      Foo foo;
      ...
      executor->Schedule([&] { Frobnicate(foo); })
      ...
    }
    // BAD! The fact that the lambda makes use of a reference to `foo` and
    // possibly `this` (if `Frobnicate` is a member function) may not be
    // apparent on a cursory inspection. If the lambda is invoked after
    // the function returns, that would be bad, because both `foo`
    // and the enclosing object could have been destroyed.
    
    {
      Foo foo;
      ...
      executor->Schedule([&] { Frobnicate(foo); })
      ...
    }
    // これはダメ!
    // ラムダ式において、fooとthis(Frobnicateがメンバ関数である場合)が
    // 使用されていますが、それは大まかにみても明らかとは言えません。
    // もし、Schedule関数から処理が戻った後に、ラムダ式が呼ばれることがあると、
    // よくないことが起こるかもしれません。ラムダ式が呼び出されたとき、
    // fooも、このラムダを取り囲んでいたオブジェクトも
    // すでに存在していないかもしれないからです。
    
    prefer to write: 以下のように書きましょう。
    {
      Foo foo;
      ...
      executor->Schedule([&foo] { Frobnicate(foo); })
      ...
    }
    // BETTER - The compile will fail if `Frobnicate` is a member
    // function, and it's clearer that `foo` is dangerously captured by
    // reference.
    
    {
      Foo foo;
      ...
      executor->Schedule([&foo] { Frobnicate(foo); })
      ...
    }
    // この方がマシ。
    // Frobnicateがメンバ関数である場合、コンパイルに失敗します。
    // また、fooが危険なキャプチャをされていることがより明確になります。
    
  • Use default capture by reference ([&]) only when the lifetime of the lambda is obviously shorter than any potential captures. 参照のデフォルトキャプチャ([&])は、ラムダ式の寿命が、その潜在的なキャプチャのすべてよりも明らかに短いときにのみ使用してください。
  • Use default capture by value ([=]) only as a means of binding a few variables for a short lambda, where the set of captured variables is obvious at a glance. 値のデフォルトキャプチャは、短いラムダ式において1~2個の変数がキャプチャされる場合で、かつ、一目見ただけでどの変数がキャプチャされているかがわかるような場合にのみ使用してください。 Prefer not to write long or complex lambdas with default capture by value. 長いラムダ式や複雑なラムダ式には、値のデフォルトキャプチャは使わないようにしましょう。
  • Keep unnamed lambdas short. 無名のラムダ式は短く保ってください。 If a lambda body is more than maybe five lines long, prefer to give the lambda a name, or to use a named function instead of a lambda. ラムダ式がおおむね5行を超えるような場合には、ラムダ式に名前をつけるか、ラムダ式ではなく名前のついたふつうの関数を使ってください。
  • Specify the return type of the lambda explicitly if that will make it more obvious to readers, as with auto. ラムダ式の戻り値の型を明示的に記述した方が可読性が上がるという場合には、そうしてください。これはautoを使うときと同様です。

テンプレートメタプログラミング

Avoid complicated template programming. 複雑なテンプレートプログラミングは避けてください。

Template metaprogramming refers to a family of techniques that exploit the fact that the C++ template instantiation mechanism is Turing complete and can be used to perform arbitrary compile-time computation in the type domain. テンプレートメタプログラミングとは、C++のテンプレート実体化の仕組みがチューリング完全であり、コンパイル時に型の世界で任意の計算を行うために使用できるという事実を利用した一連のテクニックを指します。

Template metaprogramming allows extremely flexible interfaces that are type safe and high performance. テンプレートメタプログラミングによって、型安全かつ高性能で、非常に柔軟なインターフェースを提供することが可能になります。 Facilities like Google Test, std::tuple, std::function, and Boost.Spirit would be impossible without it. Google Teststd::tuplestd::function、Boost.Spiritのような仕組みは、テンプレートメタプログラミングがなければ実現できません。

The techniques used in template metaprogramming are often obscure to anyone but language experts. テンプレートメタプログラミングにおいて使われるテクニックは、言語に精通していない人には、わかりにくいものです。 Code that uses templates in complicated ways is often unreadable, and is hard to debug or maintain. 複雑な方法でテンプレートを使っているコードは、可読性が低く、デバッグやメンテナンスが難しいものばかりです。

Template metaprogramming often leads to extremely poor compiler time error messages: even if an interface is simple, the complicated implementation details become visible when the user does something wrong. また、テンプレートメタプログラミングを使っていると、コンパイル時のエラーメッセージが非常に貧弱なものになることがあります。たとえ、インターフェースが単純なものであっても、ユーザが何かを間違えたときに、その複雑な実装の詳細が見えるようになってしまうことがあります。

Template metaprogramming interferes with large scale refactoring by making the job of refactoring tools harder. テンプレートメタプログラミングは、リファクタリングツールの仕事を困難にし、大規模なリファクタリングを阻害します。 First, the template code is expanded in multiple contexts, and it's hard to verify that the transformation makes sense in all of them. 第一に、テンプレートコードは様々な文脈で展開されますが、展開されたそれらのすべてが正しく変換されているかどうかを確かめるのが困難です。 Second, some refactoring tools work with an AST that only represents the structure of the code after template expansion. 第二に、リファクタリングツールの中には、テンプレートを展開した後のコードの構造のみを含むASTを用いて動作するものが存在します。 It can be difficult to automatically work back to the original source construct that needs to be rewritten. それらのツールが、書き換えの対象となる元のソースコードの構造を自動的に復元することは困難でしょう。

Template metaprogramming sometimes allows cleaner and easier-to-use interfaces than would be possible without it, but it's also often a temptation to be overly clever. ときに、テンプレートメタプログラミングによって、きれいで、使いやすいインターフェースを提供することができます。しかし、同時に、必要以上にうまい実装をしようと感じさせられてしまう魅力も持ち合わせています。 It's best used in a small number of low level components where the extra maintenance burden is spread out over a large number of uses. テンプレートは低レベルで少数のコンポーネントに使われることがベストであり、さもなくば、多くのコードに過剰なメンテナンスのための負荷が広がってしまうことになるかもしれません。

Think twice before using template metaprogramming or other complicated template techniques; think about whether the average member of your team will be able to understand your code well enough to maintain it after you switch to another project, or whether a non-C++ programmer or someone casually browsing the code base will be able to understand the error messages or trace the flow of a function they want to call. テンプレートメタプログラミングやその他の複雑なテンプレートのテクニックを使おうとする前に、もう一度よく考えてください。あなたのプロジェクトチームの平均的なメンバーは、あなたがチームを抜けた後でも、そのコードを十分に理解してメンテナンスすることができるでしょうか。あるいは、C++プログラマでない人や他の誰かがカジュアルにコードベースを見たときに、エラーメッセージを理解したり、呼ぼうとする関数のフローを追いかけることができるでしょうか。 If you're using recursive template instantiations or type lists or metafunctions or expression templates, or relying on SFINAE or on the sizeof trick for detecting function overload resolution, then there's a good chance you've gone too far. もし、あなたがテンプレートのインスタンス化や型リストやメタ関数や式テンプレートを再帰的に使おうとしていたり、あるいは、SFINAEやsizeofトリックに基づいて関数のオーバーロードを解決しようとしているとしたら、それらは、大抵、あなたがあまりにも遠くに来てしまったことを意味しています。

If you use template metaprogramming, you should expect to put considerable effort into minimizing and isolating the complexity. テンプレートメタプログラミングを使うのであれば、その複雑さを最小化、分離することに対する相応の努力を払わなくてはなりません。 You should hide metaprogramming as an implementation detail whenever possible, so that user-facing headers are readable, and you should make sure that tricky code is especially well commented. 可能であれば、メタプログラミングは実装の詳細として隠されるべきでしょう。そうすることで、あなたのユーザが目にするヘッダは可読性が高くなります。また、トリッキーなコードには特にしっかり確実にコメントを残すようにしてください。 You should carefully document how the code is used, and you should say something about what the "generated" code looks like. コードを使い方については、注意してドキュメント化してください。その際、"生成されるコード"の外観についても何かしら言及しておいてください。 Pay extra attention to the error messages that the compiler emits when users make mistakes. ユーザがミスを犯した場合にコンパイラが生成するであろうエラーメッセージにも特別の注意を払ってください。 The error messages are part of your user interface, and your code should be tweaked as necessary so that the error messages are understandable and actionable from a user point of view. このエラーメッセージはあなたが提供するユーザインターフェースの一部なのです。ユーザが何かを間違えたときに、ユーザにとって理解可能であり、どうすればよいかわかるようなエラーメッセージが生成されるよう、コードは調整されていなければなりません。

boost

Use only approved libraries from the Boost library collection. boostのうち、あらかじめ認められたライブラリのみを使用することができます。

The Boost library collection is a popular collection of peer-reviewed, free, open-source C++ libraries. boostライブラリコレクションは、ピアレビュー済み、フリー、オープンソースのC++ライブラリの有名なコレクションです。

Boost code is generally very high-quality, is widely portable, and fills many important gaps in the C++ standard library, such as type traits and better binders. 一般に、boostのコードはとても品質が良く、広い移植性を持ち、型traitsやよりよいバインダなどを持つように、C++の標準ライブラリの隙間を埋めてくれます。

Some Boost libraries encourage coding practices which can hamper readability, such as metaprogramming and other advanced template techniques, and an excessively "functional" style of programming. boostライブラリの中には、メタプログラミングやその他の先進的なテンプレートテクニックを取り入れたり、過度に「機能本意(functional)」なプログラミングスタイルを採用したりと、コードの可読性を妨げるコーディング手法を推奨しているものもあります。

In order to maintain a high level of readability for all contributors who might read and maintain code, we only allow an approved subset of Boost features. コードを読みメンテナンスを行うすべてのコントリビュータのために、コードは高い可読性が保たれていなければなりません。 可読性を維持するため、あらかじめ許可されたboostのサブセットのみが使用を認められています。 Currently, the following libraries are permitted: 現在のところ使用が認められてるライブラリは下記のとおりです。

We are actively considering adding other Boost features to the list, so this list may be expanded in the future. boostの他の機能については、随時リストへの追加が検討されています。今後、このリストは拡張されることがあります。

The following libraries are permitted, but their use is discouraged because they've been superseded by standard libraries in C++11: 以下に記載するライブラリも使用を認められていますが、既にC++11に標準ライブラリとして取り入れられているため、非推奨です。

std::hash

Do not define specializations of std::hash. std::hashの特殊化を定義してはいけません。

std::hash<T> is the function object that the C++11 hash containers use to hash keys of type T, unless the user explicitly specifies a different hash function. std::hash<T>は、C++11のハッシュコンテナにおいて、ユーザが明示的にハッシュ関数を指定しない場合に使われる、型Tのキーのハッシュ値を生成する関数オブジェクトです。 For example, std::unordered_map<int, string> is a hash map that uses std::hash<int> to hash its keys, whereas std::unordered_map<int, string, MyIntHash> uses MyIntHash. たとえば、std::unordered_map<int, string>は、そのキーのハッシュ値のためにstd::hash<int>を使うハッシュマップです。その一方で、std::unordered_map<int, string, MyIntHash>は、キーのハッシュ値のためにMyIntHashを使うハッシュマップです。

std::hash is defined for all integral, floating-point, pointer, and enum types, as well as some standard library types such as string and unique_ptr. std::hashは、すべての整数型、浮動小数点型、ポインタ、列挙型、stringunique_ptrなどのいくつかの標準ライブラリの型に対して定義されています。 Users can enable it to work for their own types by defining specializations of it for those types. ユーザが用意した独自の型についても、その型に対する特殊化を定義すれば、動作させることが可能です。

std::hash is easy to use, and simplifies the code since you don't have to name it explicitly. std::hashは、扱いやすく、独自に名前を明示する必要もないので、コードが単純になります。 Specializing std::hash is the standard way of specifying how to hash a type, so it's what outside resources will teach, and what new engineers will expect. std::hash を特殊化するやり方は、型のハッシュ値を得る方法を定義する標準的なものです。つまり、これは、外部の教材が教えている手法であり、新しいエンジニアが期待している手法であると言えます。

std::hash is hard to specialize. std::hashの特殊化は難しいです。 It requires a lot of boilerplate code, and more importantly, it combines responsibility for identifying the hash inputs with responsibility for executing the hashing algorithm itself. std::hashの特殊化のためには、定型コードをたくさん書かねばならず、さらに、入力されたハッシュを識別することと、ハッシュアルゴリズムを実行することとの両方の責任を負わなくてはなりません。 The type author has to be responsible for the former, but the latter requires expertise that a type author usually doesn't have, and shouldn't need. 型の作者は前者の責任は負わなくてはなりませんが、後者の責任を負うためには、型の作者が通常持たないような専門的な知識を必要としますし、本来そのような知識が必要とされるべきでもありません。 The stakes here are high because low-quality hash functions can be security vulnerabilities, due to the emergence of hash flooding attacks . ここは大事なところです。hash flooding attackのような攻撃手段が存在しているため、品質の低いハッシュ関数はそれだけでセキュリティ上の脆弱性となることがあります。

Even for experts, std::hash specializations are inordinately difficult to implement correctly for compound types, because the implementation cannot recursively call std::hash on data members. 専門的化にとってさえも、合成型に対するstd::hashの特殊化を正しく実装するのは非常に困難です。なぜならば、その実装は、データメンバに対するstd::hashを再帰的に呼び出すことができないからです。 High-quality hash algorithms maintain large amounts of internal state, and reducing that state to the size_t bytes that std::hash returns is usually the slowest part of the computation, so it should not be done more than once. 品質の高いハッシュアルゴリズムは、大量の内部状態を管理し、それらの内部状態をstd::hashが返すsize_tに落とし込みますが、この部分が計算処理におけるもっとも遅い部分となるのが通常であり、一度ハッシュ値を求めたのであれば、それ以上改めて計算しなおすべきではありません。

Due to exactly that issue, std::hash does not work with std::pair or std::tuple, and the language does not allow us to extend it to support them. これらの問題が原因で、std::hashstd::pairstd::tupleには対応できず、言語は我々にこれらをサポートするための拡張を行うことも許していません。

You can use std::hash with the types that it supports "out of the box", but do not specialize it to support additional types. すでに使えるようになっている型に対してstd::hashを使うのはかまいません。しかし、新しい型をサポートするためにstd::hashの特殊化を定義してはいけません。 If you need a hash table with a key type that std::hash does not support, consider using legacy hash containers (e.g. hash_map) for now; they use a different default hasher, which is unaffected by this prohibition. std::hashが使えない型をキーとしたハッシュテーブルを使いたい場合は、現状はレガシーなハッシュコンテナ(hash_map)などを使用することを検討してください。これらは、デフォルトで別のハッシュ関数を使っており、それらがこの禁止ルールには抵触することはありません。

If you want to use the standard hash containers anyway, you will need to specify a custom hasher for the key type, e.g. どうしても標準のハッシュコンテナを使いたい場合は、次のような、キーの型に対するカスタムのハッシュ化オブジェクトを定義してください。

std::unordered_map<MyKeyType, Value, MyKeyTypeHasher> my_map;

Consult with the type's owners to see if there is an existing hasher that you can use; otherwise work with them to provide one, or roll your own. その型の作者に、利用可能な既存のハッシュ関数等がないか確認してください。ハッシュ関数が存在しない場合は、型の作者と連携してそれを作るか、あるいは、自ら作るかです。

We are planning to provide a hash function that can work with any type, using a new customization mechanism that doesn't have the drawbacks of std::hash. 我々は、いかなる型に対しても動作するハッシュ関数を提供することを計画しています。このハッシュ関数は、新しいカスタム化のための仕組みを採用し、std::hashのような欠点は持ちません。

C++11

Use libraries and language extensions from C++11 when appropriate. C++11のライブラリや言語拡張は、それが適切な時に、使用してください。 Consider portability to other environments before using C++11 features in your project. プロジェクトでC++11の機能を使う前に、他の環境に対する移植性について検討してください。

C++11 contains significant changes both to the language and libraries. C++11は、言語とライブラリの両方において大きな変更が加えられています。

C++11 was the official standard until august 2014, and is supported by most C++ compilers. C++11は2014年の8月から標準化され、多くのC++コンパイラによってサポートされています。 It standardizes some common C++ extensions that we use already, allows shorthands for some operations, and has some performance and safety improvements. C++11によって、我々がすでに使っているような、いくつかのC++の拡張が標準化され、操作を簡潔に記述できるようになったり、パフォーマンスや安全性が向上したりしています。

The C++11 standard is substantially more complex than its predecessor (1,300 pages versus 800 pages), and is unfamiliar to many developers. 標準C++11は、以前のC++よりもさらに複雑となりました(旧仕様が800ページであるのに対して、新仕様は1,300ページもあります)。そして、多くの開発者にとっては馴染みの薄いものです。 The long-term effects of some features on code readability and maintenance are unknown. コードの可読性やメンテナンス性の面から見て、いくつかの機能における長期的な影響はまだ不明です。 We cannot predict when its various features will be implemented uniformly by tools that may be of interest, particularly in the case of projects that are forced to use older versions of tools. 特に、古いバージョンのツールを使わなくてはならないようなプロジェクトに当てはまることですが、我々は、いつまで待てば、我々が関心を払うツール群において、これらの様々な機能が一様に実装されるのか、予測することができません。

As with Boost, some C++11 extensions encourage coding practices that hamper readability—for example by removing checked redundancy (such as type names) that may be helpful to readers, or by encouraging template metaprogramming. boostを使う場合のように、いくつかのC++11拡張は、可読性を低下させるようなコーディングプラクティスを奨励します。たとえば、型名などの読者の助けになるはずの冗長性を省いてしまったり、テンプレートメタプログラミングを奨励したりします。 Other extensions duplicate functionality available through existing mechanisms, which may lead to confusion and conversion costs. 他の拡張は、既存のメカニズムを通してすでに機能的に実現可能であったことを再発明しており、それらは混乱や対話のためのコストを招き入れるかもしれません。

C++11 features may be used unless specified otherwise. 使用してはならないとあらかじめ決められている場合を除いて、C++11の機能を使用してかまいません。 In addition to what's described in the rest of the style guide, the following C++11 features may not be used: 本ガイドの他の部分で説明している事柄に加えて、以下に示すC++11の機能は使ってはいけません。

  • Compile-time rational numbers (<ratio>), because of concerns that it's tied to a more template-heavy interface style. コンパイル時有理数(<ratio>)。より重いテンプレートを使ったインターフェースのスタイルと紐付いているため。
  • The <cfenv> and <fenv.h> headers, because many compilers do not support those features reliably. <cfenv><fenv.h>ヘッダ。多くのコンパイラにおいて、これらの機能に対する信頼性がないため。
  • Ref-qualifiers on member functions, such as void X::Foo() & or void X::Foo() &&, because of concerns that they're an overly obscure feature. void X::Foo() &void X::Foo() &&のような、メンバ関数に対する参照修飾子。あまりにもこの機能の知名度が低いため。

非標準の拡張

Nonstandard extensions to C++ may not be used unless otherwise specified. C++に対する非標準の拡張は、あらかじめ決められているものを除いて使用してはいけません。

Compilers support various extensions that are not part of standard C++. コンパイラは、C++の標準にはない、様々な拡張を提供しています。 Such extensions include GCC's __attribute__, intrinsic functions such as __builtin_prefetch, designated initializers (e.g. Foo f = {.field = 3}), inline assembly, __COUNTER__, __PRETTY_FUNCTION__, compound statement expressions (e.g. foo = ({ int x; Bar(&x); x }), variable-length arrays and alloca(), and the a?:b syntax. たとえば、GCCの__attribute__や、__builtin_prefetchのようなintrinsic関数、Foo f = {.field = 3}のようなdesignated initializer、インラインアセンブリ、__COUNTER____PRETTY_FUNCTION__foo = ({ int x; Bar(&x); x })のようなcompound statement expression、可変長配列とalloca()a?:bといった文法などです。

  • Nonstandard extensions may provide useful features that do not exist in standard C++. 非標準の拡張は、標準C++にない便利な機能を提供します。 For example, some people think that designated initializers are more readable than standard C++ features like constructors. たとえば、designated initializerは、標準C++のコンストラクタよりも可読性があると考える人もいます。
  • Important performance guidance to the compiler can only be specified using extensions. パフォーマンスに関する重要なガイドをコンパイラに伝えるためには、このような拡張機能を使用してのみ指定できます。
  • Nonstandard extensions do not work in all compilers. 非標準の機能はすべてのコンパイラでは動きません。 Use of nonstandard extensions reduces portability of code. 非標準の機能を使用するとコードの移植性が低下します。
  • Even if they are supported in all targeted compilers, the extensions are often not well-specified, and there may be subtle behavior differences between compilers. ターゲットとするコンパイラのすべてでサポートされている機能であっても、このような拡張は十分に仕様が決められていない場合があり、異なるコンパイラ間で微妙に異なる動作をすることもあります。
  • Nonstandard extensions add to the language features that a reader must know to understand the code. 非標準の拡張によって、コードの読者がコードを理解するために必要とする知識の量が増えます。

Do not use nonstandard extensions. 非標準の機能は使ってはいけません。 You may use portability wrappers that are implemented using nonstandard extensions, so long as those wrappers are provided by a designated project-wide portability header. プロジェクトにおいて、そのプロジェクト内で使用するヘッダとして、非標準の拡張機能に関する移植性を保つためのラッパーが提供されている場合は、それらを通してのみ非標準の機能を使用してもかまいません。

エイリアス

Public aliases are for the benefit of an API's user, and should be clearly documented. publicなエイリアスはAPIのユーザにとって有用なものです。それらは、明確にドキュメント化されていなければなりません。

There are several ways to create names that are aliases of other entities: 他のエンティティのエイリアスとして名前をつけるためには、以下に例を示すとおり、いくつかの方法があります。

typedef Foo Bar;
using Bar = Foo;
using other_namespace::Foo;

Like other declarations, aliases declared in a header file are part of that header's public API unless they're in a function definition, in the private portion of a class, or in an explicitly-marked internal namespace. エイリアスは、関数の定義内や、クラスのprivateな部分、あるいは内部用と明示された名前空間の中で宣言されている場合を除いて、他の宣言と同様に、ヘッダファイルにおいて、そのヘッダの持つpublicなAPIの一部として宣言されます。 Aliases in such areas or in .cc files are implementation details (because client code can't refer to them), and are not restricted by this rule. 先に述べたような場所や、.ccファイルにあるエイリアスは、クライアントのコードが参照できない実装の詳細の一部であるため、このルールによる制限は受けません。

  • Aliases can improve readability by simplifying a long or complicated name. エイリアスは、長い複雑な名前を単純化するため、可読性を高めます。
  • Aliases can reduce duplication by naming in one place a type used repeatedly in an API, which might make it easier to change the type later. エイリアスは、APIにおいて型名が繰り返し使われる場合に、型に名前をつけることで、その重複を減らします。こうすることで、後で型を変更するのが容易になるかもしれません。
  • When placed in a header where client code can refer to them, aliases increase the number of entities in that header's API, increasing its complexity. クライアントコードが参照できるヘッダでエイリアスが宣言されるとき、それらはそのヘッダのAPIが提供するエンティティの数を増やすため、複雑性が増します。
  • Clients can easily rely on unintended details of public aliases, making changes difficult. 意図しないpublicエイリアスがあると、クライアントは簡単にそれに依存してしまうことができ、それによって後の変更が難しくなります。
  • It can be tempting to create a public alias that is only intended for use in the implementation, without considering its impact on the API, or on maintainability. エイリアスを認めることは、APIやそのメンテナンス性に対する影響をよく考えず、実装で使用するだけの目的でpublicなエイリアスを作ってしまうことへの誘惑となりえます。
  • Aliases can create risk of name collisions エイリアスは名前が衝突するリスクを生み出します。
  • Aliases can reduce readability by giving a familiar construct an unfamiliar name 馴染みのある構造に馴染みのない名前のエイリアスをつけてしまうと可読性が低下します。
  • Type aliases can create an unclear API contract: it is unclear whether the alias is guaranteed to be identical to the type it aliases, to have the same API, or only to be usable in specified narrow ways 型のエイリアスは、APIの規約を不明瞭にする場合があります。それは、エイリアスが常に同一の型へのエイリアスであり同じAPIを持っていることが保証されているのか、はたまた、指定されている狭い方法でしか使用できないのかがわからない場合などです。

Don't put an alias in your public API just to save typing in the implementation; do so only if you intend it to be used by your clients. 実装においてタイピングする文字の数を減らすためにpublicなAPIとしてエイリアスを配置してはいけません。クライアントに使ってもらうことを目的としている場合に限り、エイリアスをpublicに配置してください。

When defining a public alias, document the intent of the new name, including whether it is guaranteed to always be the same as the type it's currently aliased to, or whether a more limited compatibility is intended. publicなエイリアスを定義するとき、その新しい名前の意図をドキュメント化してください。また、ドキュメントには、その名前がその時点で指していた型と常に同一の型を指し続けることが保証されているか、あるいはより限られた互換性が目的とされているのかということも含めてください。 This lets the user know whether they can treat the types as substitutable or whether more specific rules must be followed, and can help the implementation retain some degree of freedom to change the alias. これによって、ユーザはその型を単に置き換えていいのか、もっと細かいルールに従う必要があるのかを判断できます。また、これによって、エイリアスの変更に対するある程度の自由度を確保することができるため、実装もしやすくなるでしょう。

Don't put namespace aliases in your public API. (See also Namespaces). namespaceのエイリアスをpublicなAPIの中においてはいけません(名前空間を参照)。

For example, these aliases document how they are intended to be used in client code: たとえば、以下の例を見てください。これらのエイリアスは、クライアントコードにおいてそれらがどう扱われることを意図しているかドキュメント化しています。

namespace a {
// Used to store field measurements. DataPoint may change from Bar* to some internal type.
// Client code should treat it as an opaque pointer.
using DataPoint = foo::bar::Bar*;

// A set of measurements. Just an alias for user convenience.
using TimeSeries = std::unordered_set<DataPoint, std::hash<DataPoint>, DataPointComparator>;
}  // namespace a
namespace a {
// フィールドの測定値を保存するために使用されます。
// DataPoint は Bar* から他の内部型に変更されるかもしれません。
// クライアントコードにおいては、これを透過的なポインタとして扱ってください。
using DataPoint = foo::bar::Bar*;

// 測定のセットです。
// これはユーザの利便性のために定義されています。
using TimeSeries = std::unordered_set<DataPoint, std::hash<DataPoint>, DataPointComparator>;
}  // namespace a

These aliases don't document intended use, and half of them aren't meant for client use: 一方、次の例のエイリアスは、意図に関するドキュメントがなく、さらにその半分はクライアントで使用する目的ですらありません。

namespace a {
// Bad: none of these say how they should be used.
using DataPoint = foo::bar::Bar*;
using std::unordered_set;  // Bad: just for local convenience
using std::hash;           // Bad: just for local convenience
typedef unordered_set<DataPoint, hash<DataPoint>, DataPointComparator> TimeSeries;
}  // namespace a
namespace a {
// ダメ: どのように扱われるべきかが書かれていない。
using DataPoint = foo::bar::Bar*;
using std::unordered_set;  // ダメ: 自分の利便性のため
using std::hash;           // ダメ: 自分の利便性のため
typedef unordered_set<DataPoint, hash<DataPoint>, DataPointComparator> TimeSeries;
}  // namespace a

However, local convenience aliases are fine in function definitions, private sections of classes, explicitly marked internal namespaces, and in .cc files: しかし、自分の利便性のためのエイリアスは、関数定義の中で定義する分には問題ありません。クラスのprivateセクションや、明示的に内部使用するとマークされているnamespaceの中や、.ccファイル内での定義も同様に問題ありません。

// In a .cc file
using std::unordered_set;
// .ccファイルの中
using std::unordered_set;

命名規則

The most important consistency rules are those that govern naming. 一貫性を保つためのもっとも重要ルールは、名前の付け方を決めることです。 The style of a name immediately informs us what sort of thing the named entity is: a type, a variable, a function, a constant, a macro, etc., without requiring us to search for the declaration of that entity. 名前のスタイルのおかげで、名前のついたそれが何であるか、型なのか、変数なのか、関数なのか、定数なのか、マクロなのか、その宣言を探しに行かなくとも、すぐにわかるのです。 The pattern-matching engine in our brains relies a great deal on these naming rules. 我々の脳内パターンマッチングエンジンは、これらの名前付けのルールに大きく依存しています。

Naming rules are pretty arbitrary, but we feel that consistency is more important than individual preferences in this area, so regardless of whether you find them sensible or not, the rules are the rules. 命名規則はかなり恣意的なものですが、我々は個人の好みよりも全体の一貫性をより重要視します。そのため、あなたがわかりやすいかと感じるかどうかに関わらず、ルールはルールと考えてください。

全般的な命名規則

Names should be descriptive; avoid abbreviation. 記述的な名前をつけてください。省略形は避けてください。

Give as descriptive a name as possible, within reason. 可能な限り、記述的な名前をつけてください。 Do not worry about saving horizontal space as it is far more important to make your code immediately understandable by a new reader. 画面の横幅を気にする必要はありません。そんなことよりも、あなたのコードが新しい読者にとってすぐに理解できるようにすることの方がはるかに重要です。 Do not use abbreviations that are ambiguous or unfamiliar to readers outside your project, and do not abbreviate by deleting letters within a word. 曖昧な省略形や、プロジェクト外のコード読者にとって馴染みが薄い省略形は使わないでください。また語句の中の文字を削る方法による省略も行わないでください。

int price_count_reader;    // No abbreviation.
int num_errors;            // "num" is a widespread convention.
int num_dns_connections;   // Most people know what "DNS" stands for.
int price_count_reader;    // 省略されていないのでOK
int num_errors;            // 「num」は広く行き渡った省略系なのでOK
int num_dns_connections;   // 多くの人は「DNS」の意味を知っているからOK
int n;                     // Meaningless.
int nerr;                  // Ambiguous abbreviation.
int n_comp_conns;          // Ambiguous abbreviation.
int wgc_connections;       // Only your group knows what this stands for.
int pc_reader;             // Lots of things can be abbreviated "pc".
int cstmr_id;              // Deletes internal letters.
int n;                     // 変数の目的がわからないのでダメ.
int nerr;                  // 曖昧な省略形なのでダメ
int n_comp_conns;          // 曖昧な省略形なのでダメ
int wgc_connections;       // グループ内のメンバーしか「wgc」の意味がわからないのでダメ
int pc_reader;             // 「pc」にはたくさんの意味があるのでダメ
int cstmr_id;              // 文字を削っているのでダメ

Note that certain universally-known abbreviations are OK, such as i for an iteration variable and T for a template parameter. 一般に広く知られている省略形を使うことはOKであることに注意してください。たとえば、イテレータ変数のiや、テンプレート引数のTなどは問題ありません。

Template parameters should follow the naming style for their category: type template parameters should follow the rules for type names, and non-type template parameters should follow the rules for variable names . テンプレート引数の命名規則は、引数が型ならば型名に従い、そうでない場合は変数名に従ってください。

ファイル名

Filenames should be all lowercase and can include underscores ( _) or dashes ( -). ファイル名はすべて小文字で、アンダースコア(_)とダッシュ(-)を含むことができます。 Follow the convention that your project uses. プロジェクトが使用するルールに従ってください。 If there is no consistent local pattern to follow, prefer "_". もし、プロジェクトでの独自の定めがない場合、アンダースコアを使用しましょう。

Examples of acceptable file names: 問題のないファイル名の例

  • my_useful_class.cc
  • my-useful-class.cc
  • myusefulclass.cc
  • myusefulclass_test.cc // _unittest and _regtest are deprecated. myusefulclass_test.cc // _unittest や _regtest は廃止

C++ files should end in .cc and header files should end in .h. C++のファイルは.ccで終わり、ヘッダは.hで終わります。 Files that rely on being textually included at specific points should end in .inc (see also the section on self-contained headers). 特定の場所にそのままインクルードされることが目的のファイルは.incで終わります(自己完結型ヘッダも参照してください)。

Do not use filenames that already exist in /usr/include, such as db.h. 既に/usr/includeに存在するファイル名をつけてはいけません(たとえばdb.h)。

In general, make your filenames very specific. 通常、ファイル名は非常に明確なものをつけてください。 For example, use http_server_logs.h rather than db.h. たとえば、db.hよりもhttp_server_logs.hとしてください。 A very common case is to have a pair of files called, e.g., foo_bar.h and foo_bar.cc, defining a class called FooBar. 非常に良くあるパターンは、ファイルをペアにして、たとえばfoo_bar.hfoo_bar.ccで、クラスFooBarを定義するようなやり方です。

Inline functions must be in a .h file. インライン関数は.hになくてはなりません。 If your inline functions are very short, they should go directly into your .h file. もし、インライン関数が非常に短いのであれば、それは.hに直接記述してください。

型名

Type names start with a capital letter and have a capital letter for each new word, with no underscores: MyExcitingClass, MyExcitingEnum. 型の名前は大文字で始まり、単語の区切りごとに大文字にします。アンダースコアは使いません。たとえば、MyExcitingClassMyExcitingEnumとします。

The names of all types — classes, structs, type aliases, enums, and type template parameters — have the same naming convention. 型(クラス、構造体、型のエイリアス、列挙型、テンプレート引数)の名前はすべて同じ命名規則に従います。 Type names should start with a capital letter and have a capital letter for each new word. 型の名前は大文字で始めて、単語の境目ごとに大文字にします。 No underscores. アンダースコアは使いません。 For example: 以下に例を示します。

// classes and structs
class UrlTable { ...
class UrlTableTester { ...
struct UrlTableProperties { ...

// typedefs
typedef hash_map<UrlTableProperties *, string> PropertiesMap;

// using aliases
using PropertiesMap = hash_map<UrlTableProperties *, string>;

// enums
enum UrlTableErrors { ...
// クラスと構造体
class UrlTable { ...
class UrlTableTester { ...
struct UrlTableProperties { ...

// typedef
typedef hash_map<UrlTableProperties *, string> PropertiesMap;

// using
using PropertiesMap = hash_map<UrlTableProperties *, string>;

// 列挙型
enum UrlTableErrors { ...

変数名

The names of variables (including function parameters) and data members are all lowercase, with underscores between words. 変数名(関数の引数も含む)や、データメンバ名は、小文字で始め単語の間にアンダースコアを使います。 Data members of classes (but not structs) additionally have trailing underscores. クラス(構造体は含まず)のデータメンバは、末尾にアンダースコアをつけます。 For instance: a_local_variable, a_struct_data_member, a_class_data_member_. たとえば、a_local_variablea_struct_data_membera_class_data_member_といった感じです。

一般的な変数名

For example: 以下に例を示します。

string table_name;  // OK - uses underscore.
string tablename;   // OK - all lowercase.
string table_name;  // OK - アンダースコアを使っている。
string tablename;   // OK - すべて小文字。
string tableName;   // Bad - mixed case.
string tableName;   // ダメ - 大文字小文字が混ざっている。

クラスのデータメンバ

Data members of classes, both static and non-static, are named like ordinary nonmember variables, but with a trailing underscore. クラスのデータメンバは、staticであるなしに関わらず、基本的にはメンバでない変数名と同様ですが、末尾にアンダースコアをつけます。

class TableInfo {
  ...
 private:
  string table_name_;  // OK - underscore at end.
  string tablename_;   // OK.
  static Pool<TableInfo>* pool_;  // OK.
};
class TableInfo {
  ...
 private:
  string table_name_;  // OK - 末尾にアンダースコアがついている。
  string tablename_;   // OK.
  static Pool<TableInfo>* pool_;  // OK.
};

構造体のデータメンバ

Data members of structs, both static and non-static, are named like ordinary nonmember variables. 構造体のデータメンバは、staticであるなしに関わらず、通常の変数と同じように名前を付けます。 They do not have the trailing underscores that data members in classes have. クラスのデータメンバと違い、末尾にアンダースコアはつけません。

struct UrlTableProperties {
  string name;
  int num_entries;
  static Pool<UrlTableProperties>* pool;
};

See Structs vs. Classes for a discussion of when to use a struct versus a class. いつ構造体を使っていつクラスを使うかに関する議論は構造体かクラスかを参照してください。

定数名

Variables declared constexpr or const, and whose value is fixed for the duration of the program, are named with a leading "k" followed by mixed case. constexprあるいはconstとして宣言され、プログラムの始めから終わりまで値が変わらない変数は、頭に「k」を付けて、大文字小文字を織り交ぜて宣言します。 For example: 以下に例を示します。

const int kDaysInAWeek = 7;

All such variables with static storage duration (i.e. statics and globals, see Storage Duration for details) should be named this way. 静的な記憶域期間を持つ変数(つまり、静的変数やグローバル変数。詳細はStorage Durationを参照)は、この方法で命名します。 This convention is optional for variables of other storage classes, e.g. automatic variables, otherwise the usual variable naming rules apply. 他の記憶域期間に分類される変数(自動変数など)に関してはこのルールの適用は任意とし、このルールを適用しない場合は、通常の変数名の規則に従うものとします。

関数名

Regular functions have mixed case; accessors and mutators may be named like variables. 通常の関数は、大文字小文字を織り交ぜて命名します。アクセッサ(Getter)やミューテータ(Setter)は、変数名の命名ルールを用いることもあります。

Ordinarily, functions should start with a capital letter and have a capital letter for each new word (a.k.a. " Camel Case " or "Pascal case"). 通常、関数名は大文字で始まり、単語の境目に大文字を使用します(「Camel Case」や「Pascal Case」とも呼ばれています)。 Such names should not have underscores. これらの名前にはアンダースコアは使いません。 Prefer to capitalize acronyms as single words (i.e. StartRpc(), not StartRPC()). 頭字語(アクロニム)はそれも1つの単語として扱いましょう(つまり、StartRPC()ではなくStartRpc()とします)。

AddTableEntry()
DeleteUrl()
OpenFileOrDie()

(The same naming rule applies to class- and namespace-scope constants that are exposed as part of an API and that are intended to look like functions, because the fact that they're objects rather than functions is an unimportant implementation detail.) (クラススコープや名前空間スコープにおいて定数がAPIとして公開され、かつ、それらが関数のように振る舞う場合は、この命名規則を適用します。それらが実際には関数ではなくオブジェクトであるという事実は、実装の詳細でありさほど重要ではありません。)

Accessors and mutators (get and set functions) may be named like variables. アクセッサ(Getter)やミューテータ(Setter)は変数名のように名前を付けてもかまいません。 These often correspond to actual member variables, but this is not required. これらは、実際のメンバ変数と紐づけられますが、必須ではありません。 For example, int count() and void set_count(int count) . たとえば、int count()void set_count(int count)です。

名前空間の名前

Namespace names are all lower-case. 名前空間名はすべて小文字にします。 Top-level namespace names are based on the project name トップレベルの名前空間は、プロジェクト名に基づいたものにします。 Avoid collisions between nested namespaces and well-known top-level namespaces. ネストされた名前空間であっても、よく知られたトップレベルの名前空間との衝突は避けてください。

The name of a top-level namespace should usually be the name of the project or team whose code is contained in that namespace. トップレベルの名前空間の名前は、通常はプロジェクト名か、そのコードが格納されるチームの名前をつけます。 The code in that namespace should usually be in a directory whose basename matches the namespace name (or subdirectories thereof). 名前空間に含まれるコードは、通常、その名前空間の名前と一致するディレクトリ(かそのサブディレクトリ)の中に置かれます。

Keep in mind that the rule against abbreviated names applies to namespaces just as much as variable names. 変数名と同様の省略に関するルールが名前空間にも適用されることに留意してください。 Code inside the namespace seldom needs to mention the namespace name, so there's usually no particular need for abbreviation anyway. 名前空間の内側のコードが、その名前空間の名前を必要とすることはめったにありません。 このため、いずれにせよ、通常は、何らかの省略形が必要になることはないでしょう。

Avoid nested namespaces that match well-known top-level namespaces. ネストされた名前空間の名前を、よく知られたトップレベルの名前空間と一致させることは避けてください。 Collisions between namespace names can lead to surprising build breaks because of name lookup rules. このような名前空間名の衝突があると、名前検索のルールによって、想定外のビルドエラーを招きかねません。 In particular, do not create any nested std namespaces. 特に、stdという名前の名前空間は、いかなるネストの階層にも作らないでください。 Prefer unique project identifiers ( websearch::index, websearch::index_util) over collision-prone names like websearch::util. websearch::utilのような衝突の起こりやすい名前は、プロジェクトのユニークな識別子をつけましょう(websearch::index, websearch::index_util)。

For internal namespaces, be wary of other code being added to the same internal namespace causing a collision (internal helpers within a team tend to be related and may lead to collisions). internalのような名前空間は、同じinternal名前空間に追加されている他のコードと衝突しないように特に注意が必要です(チーム内での内部用のヘルパ同士が、関係を持ってしまう傾向があり、それによって衝突を引き起こすかもしれません)。 In such a situation, using the filename to make a unique internal name is helpful ( websearch::index::frobber_internal for use in frobber.h) このような場合は、ファイル名を使ってユニークな内部名を作る方法が役立ちます(frobber.hでは、websearch::index::frobber_internalを使います)。

列挙型の名前

Enumerators (for both scoped and unscoped enums) should be named either like constants or like macros: either kEnumName or ENUM_NAME. 列挙型(スコープ内のもそうでないものも)は、定数(kEnumName)かマクロ(ENUM_NAME)のどちらかのルールに従います。

Preferably, the individual enumerators should be named like constants. 列挙型の個々の値は定数のルールに従いましょう。. However, it is also acceptable to name them like macros. しかし、マクロの命名規則に従ってもよいとします。 The enumeration name, UrlTableErrors (and AlternateUrlTableErrors), is a type, and therefore mixed case. 列挙型の名前はUrlTableErrors(や、AlternateUrlTableErrors)のように、型名に従い、大文字小文字を織り交ぜて定義します。

enum UrlTableErrors {
  kOK = 0,
  kErrorOutOfMemory,
  kErrorMalformedInput,
};
enum AlternateUrlTableErrors {
  OK = 0,
  OUT_OF_MEMORY = 1,
  MALFORMED_INPUT = 2,
};

Until January 2009, the style was to name enum values like macros. 2009年1月までは、列挙値はマクロの命名規則に従っていました。 This caused problems with name collisions between enum values and macros. しかし、これによって列挙値とマクロとの間で名前が衝突する問題が起きました。 Hence, the change to prefer constant-style naming was put in place. それゆえに、定数と同じ命名規則に従うようルールを変更しました。 New code should prefer constant-style naming if possible. 新しいコードは、可能な限り、定数と同様の命名規則を使ってください。 However, there is no reason to change old code to use constant-style names, unless the old names are actually causing a compile-time problem. しかし、古いコードについては、コンパイル時に名前の問題が起きない限りは、それらを新ルールにあわせて書き換える理由はありません。

マクロ名

You're not really going to define a macro , are you? If you do, they're like this: MY_MACRO_THAT_SCARES_SMALL_CHILDREN. 本当はマクロを定義しようだなんて思ってないですよね?  マクロを定義する場合は、MY_MACRO_THAT_SCARES_SMALL_CHILDREN のようにします。

Please see the description of macros ; in general macros should not be used. まず、マクロの詳細を参照してください。通常、マクロは使用されるべきではありません However, if they are absolutely needed, then they should be named with all capitals and underscores. しかし、どうしてもマクロが必要な場合は、すべて大文字にし、アンダースコアを使って名前をつけます。

#define ROUND(x) ...
#define PI_ROUNDED 3.0

命名規則の例外

If you are naming something that is analogous to an existing C or C++ entity then you can follow the existing naming convention scheme. 既存のCやC++のエンティティと類似したものに名前を付ける場合、既存の命名規則に従ってもかまいません。

bigopen()
function name, follows form of open() open()の形に従った関数名。
uint
typedef
bigpos
struct or class, follows form of pos posの形に従ったstructclass
sparse_hash_map
STL-like entity; follows STL naming conventions STLの命名規則に従った、STLライクなエンティティ。
LONGLONG_MAX
a constant, as in INT_MAX INT_MAXのような定数。

コメント

Though a pain to write, comments are absolutely vital to keeping our code readable. コメントを書くのはしんどいですが、コードの可読性を保つために、コメントはなくてはならないものです。 The following rules describe what you should comment and where. このルールでは、どこにどのようなコメントを残すべきかを説明します。 But remember: while comments are very important, the best code is self-documenting. ひとつ忘れないでほしいことは、確かにコメントは非常に重要なものですが、それよりもコード自身がドキュメントの役割をしている状態がベストだということです。 Giving sensible names to types and variables is much better than using obscure names that you must then explain through comments. 型や変数に、曖昧な名前をつけてコメントするよりも、コメント不要の適切な名前をつけるほうが、はるかに優れています。

When writing your comments, write for your audience: the next contributor who will need to understand your code. コメントを書くときは、読者を意識してください。 あなたが書いたコードを次に担当する人が理解できるようにコメントを記述してください。 Be generous — the next one may be you! あるいは、次の担当者は自分かもしれません。惜しみなくコメントを書きましょう。

訳者注: 本日本語版ガイドではコード例中のコメントも日本語に訳していますが、本来コメントは英語で行われなくてはならないでしょう。

コメントのスタイル

Use either the // or /* */ syntax, as long as you are consistent. コメントには、一貫性が保たれている限り、///* */のどちらを使ってもかまいません。

You can use either the // or the /* */ syntax; however, // is much more common. コメントには、///* */のどちらの文法を使ってもかまいません。しかし、//の方がはるかに一般的です。 Be consistent with how you comment and what style you use where. どのスタイルでどこにどのようにコメントをつけるかは、一貫性を保ってください。

ファイルに対するコメント

Start each file with license boilerplate. 各ファイルは、ライセンスに関する定型文で始めてください。

File comments describe the contents of a file. ファイル全体に掛かるコメントでは、そのファイルに含まれる内容を説明します。 If a file declares, implements, or tests exactly one abstraction that is documented by a comment at the point of declaration, file comments are not required. そのファイルにおいてただ1つの概念だけを宣言または実装、テストしていて、かつ、それに関するコメントが宣言のすぐ近くにある場合は、ファイルを説明するコメントは必須というわけではありません。 All other files must have file comments. しかし、それ以外の場合は、各ファイルにはファイルを説明するコメントを書かなくてはなりません。

法的な注意事項と著者に関する行

Every file should contain license boilerplate. すべてのファイルに、ライセンスに関する定型文を含めてください。 Choose the appropriate boilerplate for the license used by the project (for example, Apache 2.0, BSD, LGPL, GPL). 定型文は、そのプロジェクトが採用しているライセンスに沿った適切なものを選択してください(たとえば、Apache 2.0, BSD, LGPL, GPL)。

If you make significant changes to a file with an author line, consider deleting the author line. 著者に関するの行を含め、ファイルに対して大きな変更を加えた場合は、著者に関する行を削除することを検討してください。

ファイルの内容に関するコメント

If a .h declares multiple abstractions, the file-level comment should broadly describe the contents of the file, and how the abstractions are related.. .hファイルが複数の概念を宣言している場合、ファイルレベルのコメントは、広くファイルの内容を説明するものにします。そして、それらの概念がどのように関係しているかを説明します。 A 1 or 2 sentence file-level comment may be sufficient. ファイルコメントは、1つか2つの文で十分でしょう。 The detailed documentation about individual abstractions belongs with those abstractions, not at the file level. 個々の概念に関するより詳細なドキュメントは、ファイル全体に向けたコメントではなく、それぞれの概念に属すべきです。

Do not duplicate comments in both the .h and the .cc. .h.ccの両方にコメントを重複させてはいけません。 Duplicated comments diverge. 重複するコメントは、いずれ分岐してしまいます。

クラスに対するコメント

Every non-obvious class declaration should have an accompanying comment that describes what it is for and how it should be used. 各クラスの宣言には、一目見ただけでわかる場合を除いて、そのクラスの目的と使用方法についてのコメントが必要です。

// Iterates over the contents of a GargantuanTable.
// Example:
//    GargantuanTableIterator* iter = table->NewIterator();
//    for (iter->Seek("foo"); !iter->done(); iter->Next()) {
//      process(iter->key(), iter->value());
//    }
//    delete iter;
class GargantuanTableIterator {
  ...
};
// GargantuanTable全体をイテレートします
// 使用例:
//    GargantuanTableIterator* iter = table->NewIterator();
//    for (iter->Seek("foo"); !iter->done(); iter->Next()) {
//      process(iter->key(), iter->value());
//    }
//    delete iter;
class GargantuanTableIterator {
  ...
};

The class comment should provide the reader with enough information to know how and when to use the class, as well as any additional considerations necessary to correctly use the class. クラスのコメントは、コードの読者がそのクラスをいつどのように使えばよいのかわかるように記述します。また、クラスを正しく扱うために必要な付加情報があればそれらも記述します。 Document the synchronization assumptions the class makes, if any. また、クラスに同期に関する前提条件が存在する場合は、それらも記述します。 If an instance of the class can be accessed by multiple threads, take extra care to document the rules and invariants surrounding multithreaded use. クラスのインスタンスが複数のスレッドからアクセスされる場合は、そのクラスをマルチスレッド下で扱う場合のルールや不定性に関しても、細心の注意を払って記述します。

The class comment is often a good place for a small example code snippet demonstrating a simple and focused usage of the class. クラスコメントは、そのクラスの使用例などの小さなコードスニペットを記載するためにも都合の良い場所です。

When sufficiently separated (e.g. .h and .cc files), comments describing the use of the class should go together with its interface definition; comments about the class operation and implementation should accompany the implementation of the class's methods. コードが.h.ccファイルとに十分に分離されているとき、そのクラスの扱い方に関するコメントはインターフェースの定義のそばにおきます。その一方で、クラスの操作や実装に関するコメントは、クラスメソッドの実装のそばに置きます。

関数に対するコメント

Declaration comments describe use of the function (when it is non-obvious); comments at the definition of a function describe operation. 関数を宣言するときのコメントは、その関数の使い方(が明らかでない場合)について説明したものにします。一方で、関数を定義するときのコメントは、その関数が行う操作について説明したものにします。

関数宣言時のコメント

Almost every function declaration should have comments immediately 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 obvious (e.g. simple accessors for obvious properties of the class). 関数が非常に単純で一目で何をするのかがわかる場合は、コメントを省略してもかまいません(たとえば、クラスプロパティへのアクセッサである場合など)。 These comments should be descriptive ("Opens the file") rather than imperative ("Open the file"); the comment describes the function, it does not tell the function what to do. これらのコメントには、命令形("Open the file")ではなく、平叙形("Opens the file")を使用します。 コメントは、関数が何をするかを表すものであり、関数に何かをさせるためのものではないからです。 In general, these comments do not describe how the function performs its task. 一般的に、これらのコメントでは、その関数がどのように処理をするかについては触れません。 Instead, that should be left to comments in the function definition. そのような内容は、ここではなく、関数を定義するときのコメントに譲るようにしてください。

Types of things to mention in comments at the function declaration: 関数の宣言のコメントで言及すべきことは以下のような内容です。

  • What the inputs and outputs are. 関数の入力と出力は何か。
  • For class member functions: whether the object remembers reference arguments beyond the duration of the method call, and whether it will free them or not. 関数がクラスメンバ関数の場合) 関数に渡した参照引数について、関数から処理が戻った後もオブジェクトが記憶し続けるか否か。また、それをオブジェクト自身が解放するか否か。
  • If the function allocates memory that the caller must free. その関数が、関数の呼び出し元が解放責任を負うようなメモリを確保するか否か。
  • Whether any of the arguments can be a null pointer. 引数にNULLを渡してもよいのか否か。
  • If there are any performance implications of how a function is used. 関数の使い方に関するパフォーマンス上の注意事項がある場合はその情報。
  • If the function is re-entrant. What are its synchronization assumptions? 関数は再入可能であるか否か。同期に関する前提条件はどのようなものか。

Here is an example: 以下に例を示します。

// Returns an iterator for this table.  It is the client's
// responsibility to delete the iterator when it is done with it,
// and it must not use the iterator once the GargantuanTable object
// on which the iterator was created has been deleted.
//
// The iterator is initially positioned at the beginning of the table.
//
// This method is equivalent to:
//    Iterator* iter = table->NewIterator();
//    iter->Seek("");
//    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;
// この表に対するイテレータを返します。
// このイテレータは不要となった際に関数の呼び出し元でdeleteする必要があります。
// また、イテレータの元となるGargantuanTableオブジェクトをdeleteした場合、
// それ以降、そのイテレータを使用してはなりません。
//
// イテレータは、初期状態で、表の先頭を指します。
//
// この関数は次と等価です。
//    Iterator* iter = table->NewIterator();
//    iter->Seek("");
//    return iter;
// もし、この関数によって返されるイテレータをすぐに別の場所にシークする場合は、
// NewIterator()関数を使用するほうが、余分なシークを避けられるため、高速です。
Iterator* GetIterator() const;

However, do not be unnecessarily verbose or state the completely obvious. コメントを不必要に冗長にしたり、完全に明らかなことをわざわざコメントしたりしてはいけません。 Notice below that it is not necessary to say "returns false otherwise" because this is implied. 以下の例において、「それ以外の場合はfalseを返します」は不要です。それは暗黙的なことだからです。

// Returns true if the table cannot hold any more entries.
bool IsTableFull();
// 表がこれ以上の要素を持てない場合、trueを返します。
bool IsTableFull();

When documenting function overrides, focus on the specifics of the override itself, rather than repeating the comment from the overridden function. オーバーライドした関数にドキュメントを書くときは、オーバーライドする前の関数に関するコメントを繰り返すよりも、オーバーライドを行う内容自体にフォーカスしてください。 In many of these cases, the override needs no additional documentation and thus no comment is required. ただし、これらの多くの場合において、オーバーライドされた関数は追加の情報を必要としないため、その場合はコメントは不要です。

When commenting constructors and destructors, remember that the person reading your code knows what constructors and destructors are for, so comments that just say something like "destroys this object" are not useful. コンストラクタやデストラクタにコメントを書くときの注意点は、コードの読者は、コンストラクタとは何か、デストラクタとは何か既に知っているということです。単に「オブジェクトを破壊します」のようなコメントは役に立ちません。 Document what constructors do with their arguments (for example, if they take ownership of pointers), and what cleanup the destructor does. コンストラクタのコメントには、コンストラクタがその引数で何をするか(たとえば、ポインタの所有権を引き取るか否か)を記述し、デストラクタのコメントには、デストラクタが何をクリーンアップするかを記述してください。 If this is trivial, just skip the comment. 記述するまでもない場合には、コメントは省略できます。 It is quite common for destructors not to have a header comment. 実際、大多数のデストラクタにおいて、ヘッダでのコメントはありません。

関数定義時のコメント

If there is anything tricky about how a function does its job, the function definition should have an explanatory comment. 関数がその処理において何かしらトリッキーなことをしている場合、関数を定義するときにそれを説明するコメントが必要です。 For example, in the definition comment you might describe any coding tricks you use, give an overview of the steps you go through, or explain why you chose to implement the function in the way you did rather than using a viable alternative. このコメントでは、たとえば、使用されているコーディングトリックを説明したり、その関数の処理手順の概要を示したり、あるいは、様々な実現方法の中からなぜこの実装方法を選んだのかという理由を説明したりすることができます。 For instance, you might mention why it must acquire a lock for the first half of the function but why it is not needed for the second half. あるいは、「関数の前半ではロックの取得を必要とするが、後半では必要としない理由」について言及することもできます。

Note you should not just repeat the comments given with the function declaration, in the .h file or wherever. .h等で行った関数宣言のコメントの内容を繰り返すだけのコメントは避けてください。 It's okay to recapitulate briefly what the function does, but the focus of the comments should be on how it does it. 関数の概要が軽く繰り返される分にはかまいませんが、どちらかというと、どのようにそれを実現しているかにフォーカスしたコメントとするようにしてください。

変数に対するコメント

In general the actual name of the variable should be descriptive enough to give a good idea of what the variable is used for. 通常、変数名には、その変数の目的がわかるような、十分記述的な名前をつけるようにします。 In certain cases, more comments are required. それでも、さらにコメントが必要とされる場合があります。

クラスデータメンバに対するコメント

The purpose of each class data member (also called an instance variable or member variable) must be clear. 各クラスのデータメンバ(インスタンス変数、メンバ変数とも呼ばれる)の目的は明確になっていなければなりません。 If there are any invariants (special values, relationships between members, lifetime requirements) not clearly expressed by the type and name, they must be commented. 変数の型や変数名だけでは明確に説明できない不変の事柄がある場合(たとえば、特殊な意味を持つ値、メンバ間の関連性、寿命に関する要件など)、それらはコメントとして書かれていなければなりません。 However, if the type and name suffice ( int num_events_; ), no comment is needed. 一方で、型と名前だけで十分ならば(int num_events_;)は、コメントは不要でしょう。

In particular, add comments to describe the existence and meaning of sentinel values, such as nullptr or -1, when they are not obvious. 特に、nullptr-1のような、特殊な意味を持つ値を使うときは、そのような値が存在することや、その意味(明らかでない場合)について、説明のためのコメントを付け足してください。 For example: 以下に例を示します。

private:
 // Used to bounds-check table accesses. -1 means
 // that we don't yet know how many entries the table has.
 int num_total_entries_;
private:
 // テーブルアクセスの境界値チェックに使います。
 // -1 は、まだテーブルにいくつの要素があるかわからないことを意味します。
 int num_total_entries_;

グローバル変数に対するコメント

All global variables should have a comment describing what they are, what they are used for, and (if unclear) why it needs to be global. すべてのグローバル変数は、その変数が何を表していて、何のために使われ、そしてなぜグローバルである必要があるのか(明確でない場合)を説明するコメントが必要です。 For example: 以下に例を示します。

// The total number of tests cases that we run through in this regression test.
const int kNumTestCases = 6;
// この回帰テストにおけるテストケースの総数
const int kNumTestCases = 6;

実装に対するコメント

In your implementation you should have comments in tricky, non-obvious, interesting, or important parts of your code. 実装コードにおけるトリッキーな部分や、明らかでない部分、興味深い部分、重要な部分について、コメントを記述してください。

解説のコメント

Tricky or complicated code blocks should have comments before them. トリッキーあるいは複雑なコードブロックの前には、コメントを記述してください。 Example: 以下に例を示します。

// Divide result by two, taking into account that x
// contains the carry from the add.
for (int i = 0; i < result->size(); i++) {
  x = (x << 8) + (*result)[i];
  (*result)[i] = x >> 1;
  x &= 1;
}
// resultを2で割る。
// xには加算からのキャリーが含まれることを考慮する。
for (int i = 0; i < result->size(); i++) {
  x = (x << 8) + (*result)[i];
  (*result)[i] = x >> 1;
  x &= 1;
}

行末コメント

Also, lines that are non-obvious should get a comment at the end of the line. 明らかでない内容が含まれる行についても、行末にコメントをつけておくようにします。 These end-of-line comments should be separated from the code by 2 spaces. 行末コメントを入れる場合、コードとの間に2つのスペースを入れます。 Example: 以下に例を示します。

// If we have enough memory, mmap the data portion too.
mmap_budget = max<int64>(0, mmap_budget - index_->length());
if (mmap_budget >= data_size_ && !MmapData(mmap_chunk_bytes, mlock))
  return;  // Error already logged.
// メモリが十分あれば、mmap the data portion too.
mmap_budget = max<int64>(0, mmap_budget - index_->length());
if (mmap_budget >= data_size_ && !MmapData(mmap_chunk_bytes, mlock))
  return;  // エラーは記録済み

Note that there are both comments that describe what the code is doing, and comments that mention that an error has already been logged when the function returns. ここでは、コードが何をしているのかに関するコメントと、関数から抜けるときにエラーが記録済みであることに言及するコメントとの、2種類のコメントが書かれていることに注意してください。

If you have several comments on subsequent lines, it can often be more readable to line them up: 後続の行にも続けてコメントを書くときは、それらを揃えたほうが読みやすいです。

DoSomething();                  // Comment here so the comments line up.
DoSomethingElseThatIsLonger();  // Two spaces between the code and the comment.
{ // One space before comment when opening a new scope is allowed,
  // thus the comment lines up with the following comments and code.
  DoSomethingElse();  // Two spaces before line comments normally.
}
std::vector<string> list{
                    // Comments in braced lists describe the next element...
                    "First item",
                    // .. and should be aligned appropriately.
                    "Second item"};
DoSomething(); /* For trailing block comments, one space is fine. */
DoSomething();                  // 行頭を調整したコメント
DoSomethingElseThatIsLonger();  // コードとコメントの間には、スペース2つ。

{ // 開き波カッコの後の、新しいスコープに対するコメントは、スペース1つでOKです。
  // 続くコメントやコードは、このように行頭をそろえます。
  DoSomethingElse();  // 通常の、スペース2つの行コメント。
}

std::vector<string> list{
                    // 波カッコのリスト内で、次の要素を説明するためのコメント。
                    "First item",
                    // これらは適切な形で整列してください。
                    "Second item"};

DoSomething(); /* 行末のブロックコメントはスペース1つでOKです。 */

関数の引数に対するコメント

When the meaning of a function argument is nonobvious, consider one of the following remedies: 関数の引数の意味が明らかでない場合、次に述べる対策のいずれかを検討してください。

  • If the argument is a literal constant, and the same constant is used in multiple function calls in a way that tacitly assumes they're the same, you should use a named constant to make that constraint explicit, and to guarantee that it holds. 引数が定数リテラルであり、かつ、同じ値を複数の関数で使用していて、しかも、それが暗黙的に同じであると仮定されているような場合は、その制限を明示し、かつ、同じ値となることを保証するため、名前つきの定数を使ってください。
  • Consider changing the function signature to replace a bool argument with an enum argument. boolの代わりにenumを使ってください。 This will make the argument values self-describing. これによって、引数の値が自分自身を説明するようにできます。
  • For functions that have several configuration options, consider defining a single class or struct to hold all the options , and pass an instance of that. 関数がいくつかの設定オプションを持つような場合、すべてのオプションを保持するような1つのクラスか構造体を定義し、そのインスタンスを関数に渡すようにしてください。 This approach has several advantages. この方法はいくつか利点があります。 Options are referenced by name at the call site, which clarifies their meaning. まず、呼び出し元において、オプションが名前によって参照されるため、意味が明確になります。 It also reduces function argument count, which makes function calls easier to read and write. また、関数の引数の数が減るため、関数呼び出し自体を読みやすく書きやすくなります。 As an added benefit, you don't have to change call sites when you add another option. さらに、将来オプションを追加するときに、呼び出し元のコードを書き換える必要がなくなります。
  • Replace large or complex nested expressions with named variables. 長くて複雑なネストを含む式は、名前付きの変数によって分割してください。
  • As a last resort, use comments to clarify argument meanings at the call site. 最後の手段として、引数の意味を明確にするためのコメントを使用してください。
Consider the following example: 次の例を考えてみましょう。
// What are these arguments?
const DecimalNumber product = CalculateProduct(values, 7, false, nullptr);
// これらの引数の意味は?
const DecimalNumber product = CalculateProduct(values, 7, false, nullptr);

versus: これに対して……

ProductOptions options;
options.set_precision_decimals(7);
options.set_use_cache(ProductOptions::kDontUseCache);
const DecimalNumber product =
    CalculateProduct(values, options, /*completion_callback=*/nullptr);
ProductOptions options;
options.set_precision_decimals(7);
options.set_use_cache(ProductOptions::kDontUseCache);
const DecimalNumber product =
    CalculateProduct(values, options, /*completion_callback=*/nullptr);

してはならないこと

Do not state the obvious. 明らかなことをわざわざコメントしてはなりません。 In particular, don't literally describe what code does, unless the behavior is nonobvious to a reader who understands C++ well. C++を十分理解している読者が見て明らかでない場合は除きますが、通常は、コードがしていることをただ説明してはいけません。 Instead, provide higher level comments that describe why the code does what it does, or make the code self describing. そのようなコメントをつける代わりに、それよりも高い次元の、たとえばそのコードがなぜそれをしているのかをコメントとして記述するか、あるいはコード自身でそれを説明するようにしてください。

Compare this: 以下のコードを比べてみましょう。
// Find the element in the vector.  <-- Bad: obvious!
auto iter = std::find(v.begin(), v.end(), element);
if (iter != v.end()) {
  Process(element);
}
// vectorの中から要素を検索する。  <-- ダメ。そんなことはコードを見れば明らか。
auto iter = std::find(v.begin(), v.end(), element);
if (iter != v.end()) {
  Process(element);
}
To this: と、
// Process "element" unless it was already processed.
auto iter = std::find(v.begin(), v.end(), element);
if (iter != v.end()) {
  Process(element);
}
// まだ処理していない要素があれば処理する。
auto iter = std::find(v.begin(), v.end(), element);
if (iter != v.end()) {
  Process(element);
}
Self-describing code doesn't need a comment. さらに、コードが説明的になっていると、コメントを必要とすらしません。 The comment from the example above would be obvious: 上の例におけるコメントは、以下のようにすると、より明確です。
if (!IsAlreadyProcessed(element)) {
  Process(element);
}

句読点と綴りと文法

Pay attention to punctuation, spelling, and grammar; it is easier to read well-written comments than badly written ones. 句読点や綴りや文法に注意してください。きちんとしたコメントは、それだけで読みやすいものです。

Comments should be as readable as narrative text, with proper capitalization and punctuation. コメントは、大文字や句読点を適切に用いたふつうの文章として読めるように記述します。 In many cases, complete sentences are more readable than sentence fragments. 多くの場合、文の断片だけの場合よりも、完全な文にするほうが読みやすいです。 Shorter comments, such as comments at the end of a line of code, can sometimes be less formal, but you should be consistent with your style. 行末のコメントなど、短いコメントは形式を崩しがちですが、スタイルには一貫性を持たせるべきです。

Although it can be frustrating to have a code reviewer point out that you are using a comma when you should be using a semicolon, it is very important that source code maintain a high level of clarity and readability. コードレビュアーからの「セミコロンを使うべきところでカンマを使っている」といった指摘にはうんざりするかもしれませんが、ソースコードの明瞭性や可読性を高く保つことは、本当に重要なことなのです。 Proper punctuation, spelling, and grammar help with that goal. 適切な句読点、正しい綴り、正しい文法は、このゴールに向かうための手助けをしてくれるでしょう。

TODOコメント

Use TODO comments for code that is temporary, a short-term solution, or good-enough but not perfect. TODOコメントは、一時的なもの、暫定対応、あるいは完璧ではないがその場しのぎにはなるようなコードに対して使用してください。

TODOs should include the string TODO in all caps, followed by the name, e-mail address, bug ID, or other identifier of the person or issue with the best context about the problem referenced by the TODO. TODOは、すべて大文字でTODOと書き、続けて、そのTODOに関する問題についてもっともよく知る人やissueに関連付く、名前やメールアドレス、バグ管理番号、その他の識別子を含めるようにします。 The main purpose is to have a consistent TODO that can be searched to find out how to get more details upon request. このルールの主な目的は、TODOに一貫性を持たせ、その件についてより詳しく知るためにはどうしたらよいか、わかるようにすることです。 A TODO is not a commitment that the person referenced will fix the problem. TODOは、「名前の書かれている人がその問題を直します」というコミットメントではありません。 Thus when you create a TODO with a name, it is almost always your name that is given. したがって、あなたがTODOを作るときは、ほとんど常にあなたの名前で作ることになるでしょう。

// TODO(kl@gmail.com): Use a "*" here for concatenation operator.
// TODO(Zeke) change this to use relations.
// TODO(bug 12345): remove the "Last visitors" feature
// TODO(kl@gmail.com): 結合のために*演算子を使うほうがいいのだが……
// TODO(Zeke) 関係を使うように直さねば……
// TODO(bug 12345): Last visitors機能は削除せねば……

If your TODO is of the form "At a future date do something" make sure that you either include a very specific date ("Fix by November 2005") or a very specific event ("Remove this code when all clients can handle XML responses."). もし、TODOが「未来のいついつ、なにをする」という形式になる場合は、必ず、具体的な日付(例:2005年11月までに直す)や、具体的なイベント(例:すべてのクライアントがXMLレスポンスを扱えるようになったらこのコードは消す)を含めるようにしてください。

非推奨な事柄に対するコメント

Mark deprecated interface points with DEPRECATED comments. 推奨されないインターフェースはDEPRECATEDというコメントでマークしてください。

You can mark an interface as deprecated by writing a comment containing the word DEPRECATED in all caps. インターフェースに、すべて大文字のDEPRECATEDという語句を含むコメントをつけることで、そのインターフェースが推奨されていないことを表せます。 The comment goes either before the declaration of the interface or on the same line as the declaration. このコメントは、インターフェースの宣言の直前か、宣言と同じ行のいずれかにつけてください。

After the word DEPRECATED, write your name, e-mail address, or other identifier in parentheses. DEPRECATEDという語句の後に、丸カッコで囲んで、自分の名前かメールアドレス、その他何らかの自分に繋がる識別子を記載してください。

A deprecation comment must include simple, clear directions for people to fix their callsites. 何かを非推奨とするためのコメントには、それの呼び出し元をどのように修正すればよいか、シンプルでわかりやすい指示が含まれていなければなりません。 In C++, you can implement a deprecated function as an inline function that calls the new interface point. C++においては、非推奨となった関数を、新しいインターフェースを呼び出すインライン関数として実装することもできます。

Marking an interface point DEPRECATED will not magically cause any callsites to change. DEPRECATEDでインターフェースをマークしても、魔法的な力が働いて、呼び出し元が自然に書き換わる、というようなことはありません。 If you want people to actually stop using the deprecated facility, you will have to fix the callsites yourself or recruit a crew to help you. もしあなたが、非推奨としたインターフェースを呼ぶのを本気でやめてほしいときは、そのコードを呼び出し元を自分自身で修正するか、手伝ってくれる仲間を集める必要があるでしょう。

New code should not contain calls to deprecated interface points. 新しいコードは、非推奨となったインターフェースの呼び出しを含むべきではありません。 Use the new interface point instead. かわりに、新しいインターフェースを使いましょう。 If you cannot understand the directions, find the person who created the deprecation and ask them for help using the new interface point. そこに書いてある指示ではどうすればいいのかわからないかったときは、そのインターフェースを非推奨とマークした人を探して、新しいインターフェースを使うためにはどのようにすればよいか訪ねてください。

コードのフォーマット

Coding style and formatting are pretty arbitrary, but a project is much easier to follow if everyone uses the same style. コーディングスタイルとフォーマットは非常に好みによるところが大きいものですが、全員で同じスタイルを使えば、プロジェクトがそれに沿うのは簡単です。 Individuals may not agree with every aspect of the formatting rules, and some of the rules may take some getting used to, but it is important that all project contributors follow the style rules so that they can all read and understand everyone's code easily. 各個人にとっては、各フォーマットルールの中には、賛同できないものもあれば、馴染み深いものもあるでしょう。 しかし、重要なことはプロジェクト内のすべてのメンバーが1つのスタイルルールに統一することであり、それによって誰もがコードを読みやすく理解しやすい状態にできるのです。

To help you format code correctly, we've created a settings file for emacs . 正しくコードをフォーマットするために、emacsの設定ファイルを用意しています。

行の長さ

Each line of text in your code should be at most 80 characters long. コードの各行の長さは、長くとも80文字までにしてください。

We recognize that this rule is controversial, but so much existing code already adheres to it, and we feel that consistency is important. このルールには議論の余地があるでしょう。しかし、既に存在する多くのコードがこのルールに沿っており、そして、我々は一貫性は重要であると考えます。

Those who favor this rule argue that it is rude to force them to resize their windows and there is no need for anything longer. このルールを推す人の主張は、コードを読むために相手にウィンドウサイズを変えさせるのは失礼なことであり、またコードはそれ以上長くする必要はないというものです。 Some folks are used to having several code windows side-by-side, and thus don't have room to widen their windows in any case. 複数のコードウィンドウを横に並べて使っていて、これ以上ウィンドウの幅を広げるスペースはないという人もいます。 People set up their work environment assuming a particular maximum window width, and 80 columns has been the traditional standard. 多くの人が、最大ウィンドウサイズを仮定した仕事環境を準備しており、それらは伝統的に80文字が標準とされてきました。 Why change it? 変える理由がありますか?

Proponents of change argue that a wider line can make code more readable. このルールを変えたがっている人の主張は、もっと長い行を使える方がコードが読みやすくなるはずだというものです。 The 80-column limit is an hidebound throwback to 1960s mainframes; modern equipment has wide screens that can easily show longer lines. 80文字という制限は1960年代のメインフレームを思い起こさせますが、現代の機器は、長い行も簡単に表示できる広いスクリーンを備えています。

80 characters is the maximum. 最大80文字とします。

Comment lines can be longer than 80 characters if it is not feasible to split them without harming readability, ease of cut and paste or auto-linking -- e.g. if a line contains an example command or a literal URL longer than 80 characters. コメントのための行は、行の分割によって可読性やコピーペーストの利便性を妨げられる場合に、1行80文字を超えてもよいとします。 これには、たとえば、80文字よりも長いコマンド例やURLなどが当てはまります。

A raw-string literal may have content that exceeds 80 characters. 生の文字列リテラルは80文字を超えてもよいものとします。 Except for test code, such literals should appear near the top of a file. ただし、ファイルの頭の方に来るようなテスト用のコードは除きます。

An #include statement with a long path may exceed 80 columns. #include文は、パスが長くなることもなるため、80文字を超えてもかまわないものとします。

You needn't be concerned about header guards that exceed the maximum length. インクルードガードも、80文字を超えることを気にする必要はありません。

非アスキー文字

Non-ASCII characters should be rare, and must use UTF-8 formatting. 非アスキー文字は滅多に使いません。もし使う場合は必ずUTF-8フォーマットでなければなりません。

You shouldn't hard-code user-facing text in source, even English, so use of non-ASCII characters should be rare. まず前提として、ユーザが目にする文字列をソースにハードコーディングしてはいけません。たとえ英語であってもダメです。このため、非アスキー文字がコード中に出てくることは滅多にありません。 However, in certain cases it is appropriate to include such words in your code. しかし、場合によっては、このような単語をコードに含めることが適切であることもあります。 For example, if your code parses data files from foreign sources, it may be appropriate to hard-code the non-ASCII string(s) used in those data files as delimiters. たとえば、あなたのコードが海外のデータファイルを解析するのであれば、非アスキーの文字列をデータの区切り文字としてソースに埋め込むのが適切かもしれません。 More commonly, unittest code (which does not need to be localized) might contain non-ASCII strings. より一般的な例として、(ローカライズの必要がない)ユニットテストのためのコードは非アスキー文字を含んでいることがあります。 In such cases, you should use UTF-8, since that is an encoding understood by most tools able to handle more than just ASCII. こういった場合は、UTF-8を使います。UTF-8は、ASCII以外に対応するほとんどのツールによって解釈できるエンコーディングだからです。

Hex encoding is also OK, and encouraged where it enhances readability — for example, "\xEF\xBB\xBF", or, even more simply, u8"\uFEFF", is the Unicode zero-width no-break space character, which would be invisible if included in the source as straight UTF-8. 16真数によるエンコーディングを使うこともできます。特に、そうすることで可読性が高まる場合はそちらのほうが推奨されます。たとえば、"\xEF\xBB\xBF"、あるいは単にu8"\uFEFF"は、Unicodeにおいて、ゼロ幅で非改行の空白文字を表します。もし、これが、ふつうのUTF-8文字としてソースコードに含められていたら、それを目で見ることはできないでしょう。

Use the u8 prefix to guarantee that a string literal containing \uXXXX escape sequences is encoded as UTF-8. \uXXXXエスケープシーケンスを含む文字列リテラルがUTF-8にエンコードされることを保証するため、u8接頭辞を使用してください。 Do not use it for strings containing non-ASCII characters encoded as UTF-8, because that will produce incorrect output if the compiler does not interpret the source file as UTF-8. ただし、ふつうのUTF-8エンコードによる非アスキー文字を含む文字列には、これを使用しないでください。コンパイラがソースファイルをUTF-8として解釈しなかった場合に、不正な出力を生成してしまいます。

You shouldn't use the C++11 char16_t and char32_t character types, since they're for non-UTF-8 text. C++11の文字型char16_tchar32_tは、UTF-8以外のエンコードのためのものであるため、使用しないでください。 For similar reasons you also shouldn't use wchar_t (unless you're writing code that interacts with the Windows API, which uses wchar_t extensively). また、同様の理由で、wchar_tも使用しないでください(ただし、wchar_tを使用するWindows APIとやりとりするコードを書いている場合は除きます)。

スペースか、タブか

Use only spaces, and indent 2 spaces at a time. スペースのみを使用してください。インデント1つにつき、スペースは2つです。

We use spaces for indentation. インデントにはスペースを使います。 Do not use tabs in your code. コードにタブを使わないでください。 You should set your editor to emit spaces when you hit the tab key. タブキーを押したときにスペースが入力されるようにエディタを設定してください。

関数宣言と関数定義

Return type on the same line as function name, parameters on the same line if they fit. 関数の戻り値の型は、1行に収まるのであれば、関数名や引数の型と同じ行に記述します。 Wrap parameter lists which do not fit on a single line as you would wrap arguments in a function call. 引数リストが1行に収まらない場合は、関数呼び出しと同様のやり方で、行を分割してください。

Functions look like this: 関数は以下のようにします。

ReturnType ClassName::FunctionName(Type par_name1, Type par_name2) {
  DoSomething();
  ...
}

If you have too much text to fit on one line: 1行が収まらないときは、以下のようにします。

ReturnType ClassName::ReallyLongFunctionName(Type par_name1, Type par_name2,
                                             Type par_name3) {
  DoSomething();
  ...
}

or if you cannot fit even the first parameter: 最初の引数からして1行に収まらないときは、以下のようにします。

ReturnType LongClassName::ReallyReallyReallyLongFunctionName(
    Type par_name1,  // 4 space indent
    Type par_name2,
    Type par_name3) {
  DoSomething();  // 2 space indent
  ...
}
ReturnType LongClassName::ReallyReallyReallyLongFunctionName(
    Type par_name1,  // インデントはスペース 4個
    Type par_name2,
    Type par_name3) {
  DoSomething();  // インデントはスペース 2個
  ...
}

Some points to note: 注意すべき点がいくつかあります。

  • Choose good parameter names. 引数の名前をよく考えて決めてください。
  • Parameter names may be omitted only if the parameter is unused and its purpose is obvious. 引数が使われない、かつ、その目的が明らかな場合に限り、その引数の名前を省略してもかまいません。
  • If you cannot fit the return type and the function name on a single line, break between them. 戻り値の型と関数名とが同じ行に収まらない場合は、その間で行を分割してください。
  • If you break after the return type of a function declaration or definition, do not indent. 戻り値の型の後で改行する場合であっても、インデントはしないでください。
  • The open parenthesis is always on the same line as the function name. 開き丸カッコは常に関数名と同じ行に書きます。
  • There is never a space between the function name and the open parenthesis. 関数名と開き丸カッコの間にはスペースを入れてはいけません。
  • There is never a space between the parentheses and the parameters. 開き丸カッコと引数の間にはスペースを入れてはいけません。
  • The open curly brace is always on the end of the last line of the function declaration, not the start of the next line. 開き波カッコは常に関数宣言の最後の行に書きます。次の行の頭ではありません。
  • The close curly brace is either on the last line by itself or on the same line as the open curly brace. 閉じ波カッコは、それ自身で最後の行とするか、開き波カッコと同じ行に書くかのいずれかです。
  • There should be a space between the close parenthesis and the open curly brace. 閉じ丸カッコと開き波カッコの間にはスペースを入れます。
  • All parameters should be aligned if possible. 可能な限り、すべての引数を整列させます。
  • Default indentation is 2 spaces. デフォルトのインデントはスペース2つです。
  • Wrapped parameters have a 4 space indent. 引数リストにおいて行を分割した場合は、インデントはスペース4つです。

Unused parameters that are obvious from context may be omitted: 以下の例のように、引数が使われない、かつ、その意味が文脈から明らかな場合は、引数を省略できます。

class Foo {
 public:
  Foo(Foo&&);
  Foo(const Foo&);
  Foo& operator=(Foo&&);
  Foo& operator=(const Foo&);
};

Unused parameters that might not be obvious should comment out the variable name in the function definition: 使われない引数でも、意味が明らかでない場合は、関数定義の引数名をコメントアウトします。

class Shape {
 public:
  virtual void Rotate(double radians) = 0;
};

class Circle : public Shape {
 public:
  void Rotate(double radians) override;
};

void Circle::Rotate(double /*radians*/) {}
// Bad - if someone wants to implement later, it's not clear what the
// variable means.
void Circle::Rotate(double) {}
// ダメ。後で誰かが実装しようとしても、引数の名前が何であったのかわからない。
void Circle::Rotate(double) {}

Attributes, and macros that expand to attributes, appear at the very beginning of the function declaration or definition, before the return type: 属性や、属性に展開されるマクロは、関数宣言や関数定義の一番最初(戻り値の型の前)に書きます。

MUST_USE_RESULT bool IsOK();

ラムダ式

Format parameters and bodies as for any other function, and capture lists like other comma-separated lists. 引数リストと関数の定義のフォーマットは他の関数と同様とします。キャプチャリストのフォーマットは他のカンマ区切りリストと同様とします。

For by-reference captures, do not leave a space between the ampersand (&) and the variable name. 参照キャプチャのアンパサンド(&)と変数名との間には、スペースを入れません。

int x = 0;
auto x_plus_n = [&x](int n) -> int { return x + n; }

Short lambdas may be written inline as function arguments. 短いラムダ式は、関数の引数としてインラインで書いてもかまいません。

std::set<int> blacklist = {7, 8, 9};
std::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.end());

関数呼び出し

Either write the call all on a single line, wrap the arguments at the parenthesis, or start the arguments on a new line indented by four spaces and continue at that 4 space indent. 関数呼び出しは1行で書くか、引数を丸カッコのところに揃えるように改行するか、スペース4つでインデントした新しい行に引数リストを書くかのいずれかとします。 In the absence of other considerations, use the minimum number of lines, including placing multiple arguments on each line where appropriate. 他に考慮すべきことがない場合は、1行に複数の引数を含めて、可能な限り少ない行数で記述してください。

Function calls have the following format: 関数呼び出しは以下のォーマットに従ってください。

bool result = DoSomething(argument1, argument2, argument3);

If the arguments do not all fit on one line, they should be broken up onto multiple lines, with each subsequent line aligned with the first argument. もし、引数が1行に収まらない場合、それらを複数の行に分割してください。その際、後続の行は最初の引数に揃えてください。 Do not add spaces after the open paren or before the close paren: 開き丸カッコの後や、閉じ丸カッコの前にスペースを入れてはいけません。

bool result = DoSomething(averyveryveryverylongargument1,
                          argument2, argument3);

Arguments may optionally all be placed on subsequent lines with a four space indent: 引数は、スペース4つでインデントされた後続行に記述することもできます。

if (...) {
  ...
  ...
  if (...) {
    bool result = DoSomething(
        argument1, argument2,  // 4 space indent
        argument3, argument4);
    ...
  }
if (...) {
  ...
  ...
  if (...) {
    bool result = DoSomething(
        argument1, argument2,  // スペース4つでインデント
        argument3, argument4);
    ...
  }

Put multiple arguments on a single line to reduce the number of lines necessary for calling a function unless there is a specific readability problem. 関数呼び出しに必要な行数を減らすため、可読性に関する特別な事情がない限り、1行に複数の引数を配置してください。 Some find that formatting with strictly one argument on each line is more readable and simplifies editing of the arguments. 人によっては、各行に1つずつ引数をおくフォーマットのほうが読みやすく、より編集しやすくなると考えるかもしれません。 However, we prioritize for the reader over the ease of editing arguments, and most readability problems are better addressed with the following techniques. しかし、我々は、編集のしやすさよりも読者のことを優先しており、可読性に関する問題は次のような方法で改善することができます。

If having multiple arguments in a single line decreases readability due to the complexity or confusing nature of the expressions that make up some arguments, try creating variables that capture those arguments in a descriptive name: 複雑な式で引数が構成され、1行に複数の引数をおくと可読性が低下してしまうという場合には、一時変数を作り、それらの引数に記述的な名前を与えてください。

int my_heuristic = scores[x] * y + bases[x];
bool result = DoSomething(my_heuristic, x, y, z);

Or put the confusing argument on its own line with an explanatory comment: あるいは、意味のわかりにくい引数を、説明的なコメントともに、個別の行に配置してください。

bool result = DoSomething(scores[x] * y + bases[x],  // Score heuristic.
                          x, y, z);
bool result = DoSomething(scores[x] * y + bases[x],  // ヒューリスティックなスコア
                          x, y, z);

If there is still a case where one argument is significantly more readable on its own line, then put it on its own line. それでもまだ、1つの引数を固有の行に書く方がずっと読みやすいという場合には、そのようにしてください。 The decision should be specific to the argument which is made more readable rather than a general policy. 全体的なポリシーよりも、引数がより読みやすくなる方法を選びましょう。

Sometimes arguments form a structure that is important for readability. ときには、引数が可読性の面で重要な構造を持つことがあります。 In those cases, feel free to format the arguments according to that structure: このような場合は、それらの引数をその構造に沿って自由に配置するようにしてください。

// Transform the widget by a 3x3 matrix.
my_widget.Transform(x1, x2, x3,
                    y1, y2, y3,
                    z1, z2, z3);
// ウィジェットを3x3行列で変形する
my_widget.Transform(x1, x2, x3,
                    y1, y2, y3,
                    z1, z2, z3);

波カッコによる初期化子リスト

Format a braced initializer list exactly like you would format a function call in its place. 波カッコによる初期化子リストは、関数呼び出しと同じようにフォーマットします。

If the braced list follows a name (e.g. a type or variable name), format as if the {} were the parentheses of a function call with that name. 波カッコのリストが型名や変数名のすぐ後に続く場合は、{}を関数呼び出しにおける丸カッコと同等と見なして扱います。 If there is no name, assume a zero-length name. 名前がない場合は、0文字の名前があると仮定します。

// Examples of braced init list on a single line.
return {foo, bar};
functioncall({foo, bar});
std::pair<int, int> p{foo, bar};

// When you have to wrap.
SomeFunction(
    {"assume a zero-length name before {"},
    some_other_function_parameter);
SomeType variable{
    some, other, values,
    {"assume a zero-length name before {"},
    SomeOtherType{
        "Very long string requiring the surrounding breaks.",
        some, other values},
    SomeOtherType{"Slightly shorter string",
                  some, other, values}};
SomeType variable{
    "This is too long to fit all in one line"};
MyType m = {  // Here, you could also break before {.
    superlongvariablename1,
    superlongvariablename2,
    {short, interior, list},
    {interiorwrappinglist,
     interiorwrappinglist2}};
// 波カッコ初期化子リストを1行に配置する場合の例
return {foo, bar};
functioncall({foo, bar});
std::pair<int, int> p{foo, bar};

// 複数行にする場合
SomeFunction(
    {"assume a zero-length name before {"},
    some_other_function_parameter);
SomeType variable{
    some, other, values,
    {"assume a zero-length name before {"},
    SomeOtherType{
        "Very long string requiring the surrounding breaks.",
        some, other values},
    SomeOtherType{"Slightly shorter string",
                  some, other, values}};
SomeType variable{
    "This is too long to fit all in one line"};
MyType m = {  // {の前で改行してもかまいません
    superlongvariablename1,
    superlongvariablename2,
    {short, interior, list},
    {interiorwrappinglist,
     interiorwrappinglist2}};

条件文

Prefer no spaces inside parentheses. 丸カッコの中にはスペースを書かかない方が好ましいです。 The if and else keywords belong on separate lines. ifelseは、別の行にします。

There are two acceptable formats for a basic conditional statement. 基本的な条件文には、2つのフォーマットが使用できます。 One includes spaces between the parentheses and the condition, and one does not. ひとつは、丸カッコと条件式の間にスペースを入れるもの。もうひとつは、スペースを入れないもの、です。

The most common form is without spaces. スペースを入れない方が多数派です。 Either is fine, but be consistent. どちらの形でも問題ありませんが、一貫性が保たれるようにしてください。 If you are modifying a file, use the format that is already present. 既存のファイルを変更するときには、既にそのコードに存在するフォーマットにあわせてください。 If you are writing new code, use the format that the other files in that directory or project use. 新しいコードを書くときには、同じディレクトリ内あるいは同じプロジェクト内にある他のファイルにあわせてください。 If in doubt and you have no personal preference, do not add the spaces. どちらを使うべきかわからない場合、個人の好みがなければ、スペースを入れない方を採用してください。

if (condition) {  // no spaces inside parentheses
  ...  // 2 space indent.
} else if (...) {  // The else goes on the same line as the closing brace.
  ...
} else {
  ...
}
if (condition) {  // 丸カッコの中にはスペースを入れない。
  ...  // スペース2つでインデント
} else if (...) {  // elseは、閉じ波カッコと同じ行におく。
  ...
} else {
  ...
}

If you prefer you may add spaces inside the parentheses: 丸カッコの中にスペースを入れる場合は次のようになります。

if ( condition ) {  // spaces inside parentheses - rare
  ...  // 2 space indent.
} else {  // The else goes on the same line as the closing brace.
  ...
}
if ( condition ) {  // 丸カッコの中にスペースがある。(きわめて少数派)
  ...  // スペース2つでインデント
} else {  // else は閉じ波カッコと同じ行におく。
  ...
}

Note that in all cases you must have a space between the if and the open parenthesis. いずれの場合でも、ifと開き丸カッコの間にはスペースをおかなくてはならないことに注意してください。 You must also have a space between the close parenthesis and the curly brace, if you're using one. また、どちらの場合でも閉じ丸カッコと波カッコの間にもスペースを入れなくてはいけません。

if(condition) {   // Bad - space missing after IF.
if (condition){   // Bad - space missing before {.
if(condition){    // Doubly bad.
if(condition) {   // ダメ。ifの後にスペースがない。
if (condition){   // ダメ。{の前にスペースがない。
if(condition){    // ダメダメ。
if (condition) {  // Good - proper space after IF and before {.
if (condition) {  // 良い。ifの後、{の前に適切にスペースがある。

Short conditional statements may be written on one line if this enhances readability. 短い条件文は、それによって可読性が増す場合は1行に書いてもかまいません。 You may use this only when the line is brief and the statement does not use the else clause. ただし、行が簡潔であり、その文にelse句がない場合に限ります。

if (x == kFoo) return new Foo();
if (x == kBar) return new Bar();

This is not allowed when the if statement has an else: 次のように、if文にelse句がある場合は、認められません。

// Not allowed - IF statement on one line when there is an ELSE clause
if (x) DoThis();
else DoThat();
// ダメ。else句があるif文が1行になっている。
if (x) DoThis();
else DoThat();

In general, curly braces are not required for single-line statements, but they are allowed if you like them; conditional or loop statements with complex conditions or statements may be more readable with curly braces. 一般的に、文が1行になるときは波カッコは必須ではありません。カッコをつける方が好きであればつけてもかまいません。条件文やループ文が複雑な条件式や文を伴う場合は、波カッコがあるほうがより読みやすいかもしれません。 Some projects require that an if must always always have an accompanying brace. プロジェクトによっては、if文にける波カッコを必須としている場合もあります。

if (condition)
  DoSomething();  // 2 space indent.

if (condition) {
  DoSomething();  // 2 space indent.
}
if (condition)
  DoSomething();  // スペース2つでインデント

if (condition) {
  DoSomething();  // スペース2つでインデント
}

However, if one part of an if- else statement uses curly braces, the other part must too: ただし、if-else文において、そのいずれかの部分で波カッコをつける場合には、必ずもう一方にもつけなくてはなりません。

// Not allowed - curly on IF but not ELSE
if (condition) {
  foo;
} else
  bar;

// Not allowed - curly on ELSE but not IF
if (condition)
  foo;
else {
  bar;
}
// ダメ。ifには波カッコがあり、elseにはない。
if (condition) {
  foo;
} else
  bar;

// ダメ。elseには波カッコがあり、ifにはない。
if (condition)
  foo;
else {
  bar;
}
// Curly braces around both IF and ELSE required because
// one of the clauses used braces.
if (condition) {
  foo;
} else {
  bar;
}
// ifとelseの両方に波カッコが必要。一方で波カッコを使っているため。
if (condition) {
  foo;
} else {
  bar;
}

ループとswitch文

Switch statements may use braces for blocks. switch文でブロックを作るために波カッコを使用できます。 Annotate non-trivial fall-through between cases. case間をfall-throughする時には、自明な場合を除いて、注釈をつけてください。 Braces are optional for single-statement loops. ループの本体が1つの文からなる場合、波カッコはつけてもつけなくてもかまいません。 Empty loop bodies should use empty braces or continue. 空のループには、波カッコによる空のブロックか、continue文を使用してください。

case blocks in switch statements can have curly braces or not, depending on your preference. switch中のcaseブロックでは、波カッコを使っても使わなくてもかまいません。 If you do include curly braces they should be placed as shown below. 波カッコを使う場合は、以下の例のように配置します。

If not conditional on an enumerated value, switch statements should always have a default case (in the case of an enumerated value, the compiler will warn you if any values are not handled). switch文の条件値が列挙型でない場合は、必ずdefaultブロックが必要です(列挙型の値によるswitch文は、caseが漏れてもコンパイラが警告してくれるでしょう)。 If the default case should never execute, simply assert: defaultブロックが絶対に実行されない場合には、単にassertします。

switch (var) {
  case 0: {  // 2 space indent
    ...      // 4 space indent
    break;
  }
  case 1: {
    ...
    break;
  }
  default: {
    assert(false);
  }
}
switch (var) {
  case 0: {  // スペース2つでインデント
    ...      // スペース4つでインデント
    break;
  }
  case 1: {
    ...
    break;
  }
  default: {
    assert(false);
  }
}

Braces are optional for single-statement loops. ひとつの文からなるループにおいて、波カッコはつけてもつけなくてもかまいません。

for (int i = 0; i < kSomeNumber; ++i)
  printf("I love you\n");

for (int i = 0; i < kSomeNumber; ++i) {
  printf("I take it back\n");
}

Empty loop bodies should use an empty pair of braces or continue, but not a single semicolon. ループ本体が空になる場合は、波カッコによる空のブロックとするか、continueを使います。セミコロンだけを書いてはいけません。

while (condition) {
  // Repeat test until it returns false.
}
for (int i = 0; i < kSomeNumber; ++i) {}  // Good - one newline is also OK.
while (condition) continue;  // Good - continue indicates no logic.
while (condition) {
  // falseが変えるまでテストを続ける。
}
for (int i = 0; i < kSomeNumber; ++i) {}  // OK。新しい1行でもOK。
while (condition) continue;  // OK。continueで、ロジックがないことを示す。
while (condition);  // Bad - looks like part of do/while loop.
while (condition);  // ダメ。do-whileループの一部に見える。

ポインタと参照の表現

No spaces around period or arrow. ピリオドやアロー演算子の周りにスペースは使いません。 Pointer operators do not have trailing spaces. ポインタ演算子の後にはスペースを使いません。

The following are examples of correctly-formatted pointer and reference expressions: 正しいフォーマットのポインタおよび参照の例を以下に示します。

x = *p;
p = &x;
x = r.y;
x = r->y;

Note that: 以下のことに注意してください。

  • There are no spaces around the period or arrow when accessing a member. メンバにアクセスするためのピリオドやアロー演算子の周りにはスペースを使いません。
  • Pointer operators have no space after the * or &. ポインタ演算子(*&)の後にはスペースを使いません。

When declaring a pointer variable or argument, you may place the asterisk adjacent to either the type or to the variable name: 変数や引数をポインタとして宣言するときは、アスタリスクを型名か変数名かのどちらにつけてもかまいません。

// These are fine, space preceding.
char *c;
const string &str;

// These are fine, space following.
char* c;
const string& str;
// これらはどちらもOK。スペースが先。
char *c;
const string &str;

// これらもOK。スペースが後。
char* c;
const string& str;
It is allowed (if unusual) to declare multiple variables in the same declaration, but it is disallowed if any of those have pointer or reference decorations. 複数の変数をまとめて宣言してもかまいません。しかし、それらの中に1つでもポインタや参照が含まれる場合は、同時に宣言してはいけません。 Such declarations are easily misread. そのような宣言は簡単に読み違えてしまうからです。
// Fine if helpful for readability.
int x, y;
// 可読性が高まる場合はOK。
int x, y;
int x, *y;  // Disallowed - no & or * in multiple declaration
char * c;  // Bad - spaces on both sides of *
const string & str;  // Bad - spaces on both sides of &
int x, *y;  // 禁止。&や*が複数宣言の中に含められている。
char * c;  // ダメ。*の前後両方にスペースがある。
const string & str;  // ダメ。&の前後両方にスペースがある。

You should do this consistently within a single file, so, when modifying an existing file, use the style in that file. ファイル内の一貫性を保つようにしてください。既存のファイルを変更する場合は、そのファイルのスタイルにあわせてください。

ブーリアンの表現

When you have a boolean expression that is longer than the standard line length, be consistent in how you break up the lines. ブーリアンの式が標準の行の長さを超えるような場合、行の区切り方に一貫性を持たせてください。

In this example, the logical AND operator is always at the end of the lines: 以下の例では、論理積演算子を常に行末においています。

if (this_one_thing > this_other_thing &&
    a_third_thing == a_fourth_thing &&
    yet_another && last_one) {
  ...
}
if (this_one_thing > this_other_thing &&
    a_third_thing == a_fourth_thing &&
    yet_another && last_one) {
  ...
}

Note that when the code wraps in this example, both of the && logical AND operators are at the end of the line. この例において、2つの&&論理積演算子が、いずれも行末に来ていることに注目してください。 This is more common in Google code, though wrapping all operators at the beginning of the line is also allowed. 演算子は次の行の頭に書いてもかまいませんが、Googleのコードにおいてよく見るのは、先のような行末に置く形です。 Feel free to insert extra parentheses judiciously because they can be very helpful in increasing readability when used appropriately. また、丸カッコを適切に扱うことで式の可読性が向上するため、丸カッコは自由に挿入してください。 Also note that you should always use the punctuation operators, such as && and ~, rather than the word operators, such as and and compl. 演算子にはandcomplのようなワードによる演算子ではなく、常に&&~のような記号による演算子を使用してください。

戻り値

Do not needlessly surround the return expression with parentheses. return文の式を不必要に丸カッコで囲んではいけません。

Use parentheses in return expr; only where you would use them in x = expr;. return expr;に丸カッコを使うのは、式がx = expr;の形をしている場合のみです。

return result;                  // No parentheses in the simple case.
// Parentheses OK to make a complex expression more readable.
return (some_long_condition &&
        another_condition);
return result;                  // シンプルなときは丸カッコは使わない。

// これはOK。複雑な式を読みやすくするために、丸カッコを使っている。
return (some_long_condition &&
        another_condition);
return (value);                // You wouldn't write var = (value);
return(result);                // return is not a function!
return (value);                // var = (value);と書いてはいけない。
return(result);                // returnは関数ではない!

変数と配列の初期化

Your choice of =, (), or {}. =か、()か、{}か、から選びます。

You may choose between =, (), and {}; the following are all correct: =か、()か、{}か、が使用できます。次の例はすべてOKです。

int x = 3;
int x(3);
int x{3};
string name = "Some Name";
string name("Some Name");
string name{"Some Name"};
int x = 3;
int x(3);
int x{3};
string name = "Some Name";
string name("Some Name");
string name{"Some Name"};

Be careful when using a braced initialization list {...} on a type with an std::initializer_list constructor. 型がstd::initializer_listを引数にとるコンストラクタを持つ場合、波カッコによる初期化子リストを使う場合は注意が必要です。 A nonempty braced-init-list prefers the std::initializer_list constructor whenever possible. 型にstd::initializer_listをとるコンストラクタがあると、空でない波カッコ初期化リストはいつでもこれを呼び出します。 Note that empty braces {} are special, and will call a default constructor if available. ただし、リストが空{}のときは特殊で、デフォルトコンストラクタ(あれば)が呼ばれます。 To force the non- std::initializer_list constructor, use parentheses instead of braces. 強制的にstd::initializer_listではないコンストラクタを呼びたい場合は、波カッコではなく丸カッコを使ってください。

std::vector<int> v(100, 1);  // A vector of 100 1s.
std::vector<int> v{100, 1};  // A vector of 100, 1.
std::vector<int> v(100, 1);  // 1が100個。
std::vector<int> v{100, 1};  // 100と1。

Also, the brace form prevents narrowing of integral types. また、整数型に波カッコによる初期化子の形を用いると、小さい型への変換を防ぐことができます。 This can prevent some types of programming errors. これによって、プログラミング上のミスを防げる場合もあります。

int pi(3.14);  // OK -- pi == 3.
int pi{3.14};  // Compile error: narrowing conversion.
int pi(3.14);  // OK。 pi == 3 だけど。
int pi{3.14};  // コンパイルエラー: より小さい型への変換

プリプロセッサディレクティブ

The hash mark that starts a preprocessor directive should always be at the beginning of the line. プリプロセッサディレクティブに使われる#は、常に行の先頭になくてはなりません。

Even when preprocessor directives are within the body of indented code, the directives should start at the beginning of the line. たとえプリプロセッサディレクティブをインデントされているコードの中に書く場合であっても、ディレクティブは行頭に記述します。

// Good - directives at beginning of line
  if (lopsided_score) {
#if DISASTER_PENDING      // Correct -- Starts at beginning of line
    DropEverything();
# if NOTIFY               // OK but not required -- Spaces after #
    NotifyClient();
# endif
#endif
    BackToNormal();
  }
// OK。プリプロセッサが行の頭にある。
  if (lopsided_score) {
#if DISASTER_PENDING      // 正しい。行頭から始める。
    DropEverything();
# if NOTIFY               // #の後ろにスペースがあってもOK(必須ではない)。
    NotifyClient();
# endif
#endif
    BackToNormal();
  }
// Bad - indented directives
  if (lopsided_score) {
    #if DISASTER_PENDING  // Wrong!  The "#if" should be at beginning of line
    DropEverything();
    #endif                // Wrong!  Do not indent "#endif"
    BackToNormal();
  }
// ダメ。ディレクティブがインデントされている。
  if (lopsided_score) {
    #if DISASTER_PENDING  // 間違い! "#if"は行頭になくてはならない。
    DropEverything();
    #endif                // 間違い! #endifをインデントしてはダメ。
    BackToNormal();
  }

クラスのフォーマット

Sections in public, protected and private order, each indented one space. クラス内のセクションはpublicprotectedprivateの順で並べ、それぞれスペース1文字でインデントします。

The basic format for a class definition (lacking the comments, see Class Comments for a discussion of what comments are needed) is: 基本的なクラス定義のフォーマットを以下に示します(コメントは省略しています。コメントについては、クラスのコメントで議論しています)

class MyClass : public OtherClass {
 public:      // Note the 1 space indent!
  MyClass();  // Regular 2 space indent.
  explicit MyClass(int var);
  ~MyClass() {}

  void SomeFunction();
  void SomeFunctionThatDoesNothing() {
  }

  void set_some_var(int var) { some_var_ = var; }
  int some_var() const { return some_var_; }

 private:
  bool SomeInternalFunction();

  int some_var_;
  int some_other_var_;
};
class MyClass : public OtherClass {
 public:      // スペース1つでインデント!
  MyClass();  // スペース2つでインデント(いつもの)
  explicit MyClass(int var);
  ~MyClass() {}

  void SomeFunction();
  void SomeFunctionThatDoesNothing() {
  }

  void set_some_var(int var) { some_var_ = var; }
  int some_var() const { return some_var_; }

 private:
  bool SomeInternalFunction();

  int some_var_;
  int some_other_var_;
};

Things to note: 次の点に注意してください。

  • Any base class name should be on the same line as the subclass name, subject to the 80-column limit. 基底クラスの名前は派生クラスの名前と同じ行に配置されるべきです。行の長さの制限にも従ってください。
  • The public:, protected:, and private: keywords should be indented one space. public:protected:private:キーワードは、スペース1つでインデントします。
  • Except for the first instance, these keywords should be preceded by a blank line. 最初のキーワードを除いて、それらの前には空行を挟みます。 This rule is optional in small classes. 小さなクラスにおいては、このルールに従わなくてもかまいません。
  • Do not leave a blank line after these keywords. これらのキーワードの後には空行を入れてはいけません。
  • The public section should be first, followed by the protected and finally the private section. publicセクションが最初、次にprotected、最後にprivateの順番にします。
  • See Declaration Order for rules on ordering declarations within each of these sections. 各セクション内における宣言の順序に関するルールについては宣言の順序を参照してください。

コンストラクタの初期化子リスト

Constructor initializer lists can be all on one line or with subsequent lines indented four spaces. コンストラクタの初期化子リストは、すべて同じ行に納めるか、行を分けて2行目以降をスペース4つでインデントして書きます。

The acceptable formats for initializer lists are: 初期化子リストの正しい例は次の通りです。

// When everything fits on one line:
MyClass::MyClass(int var) : some_var_(var) {
  DoSomething();
}

// If the signature and initializer list are not all on one line,
// you must wrap before the colon and indent 4 spaces:
MyClass::MyClass(int var)
    : some_var_(var), some_other_var_(var + 1) {
  DoSomething();
}

// When the list spans multiple lines, put each member on its own line
// and align them:
MyClass::MyClass(int var)
    : some_var_(var),             // 4 space indent
      some_other_var_(var + 1) {  // lined up
  DoSomething();
}

// As with any other code block, the close curly can be on the same
// line as the open curly, if it fits.
MyClass::MyClass(int var)
    : some_var_(var) {}
// 1行にすべて収まるとき
MyClass::MyClass(int var) : some_var_(var) {
  DoSomething();
}

// 1行に収まらない場合は、コロンの手前で行を区切り、
// スペース4つでインデントしなくてはならない。
MyClass::MyClass(int var)
    : some_var_(var), some_other_var_(var + 1) {
  DoSomething();
}

// 初期化子リストが複数に分かれる場合は、
// 各変数ごとに1行を使うようにし、それらを整列させる。
MyClass::MyClass(int var)
    : some_var_(var),             // スペース4つでインデント。
      some_other_var_(var + 1) {  // 行頭は揃える。
  DoSomething();
}

// 他のコードブロックと同様に、1行に収まる場合は
// 閉じ波カッコと開き波カッコとを同じ行においてもよい。
MyClass::MyClass(int var)
    : some_var_(var) {}

名前空間のフォーマット

The contents of namespaces are not indented. 名前空間内の内容はインデントしません。

Namespaces do not add an extra level of indentation. 名前空間ではインデントを足しません。 For example, use: たとえば、次のように使用します。

namespace {

void foo() {  // Correct.  No extra indentation within namespace.
  ...
}

}  // namespace
namespace {

void foo() {  // 正しい。名前空間ではインデントしない。
  ...
}

}  // namespace

Do not indent within a namespace: 名前空間の中ではインデントしてはいけません。

namespace {

  // Wrong.  Indented when it should not be.
  void foo() {
    ...
  }

}  // namespace
namespace {

  // 間違い。インデントされるべきではない。
  void foo() {
    ...
  }

}  // namespace

When declaring nested namespaces, put each namespace on its own line. ネストされた名前空間を宣言するときは、各名前空間ごとに別の行にわけます。

namespace foo {
namespace bar {
namespace foo {
namespace bar {

水平方向の空白

Use of horizontal whitespace depends on location. 水平方向の空白は場所に応じて使いわけます。 Never put trailing whitespace at the end of a line. 行末に空白をおいてはいけません。

全般

void f(bool b) {  // Open braces should always have a space before them.
  ...
int i = 0;  // Semicolons usually have no space before them.
// Spaces inside braces for braced-init-list are optional.  If you use them,
// put them on both sides!
int x[] = { 0 };
int x[] = {0};

// Spaces around the colon in inheritance and initializer lists.
class Foo : public Bar {
 public:
  // For inline function implementations, put spaces between the braces
  // and the implementation itself.
  Foo(int b) : Bar(), baz_(b) {}  // No spaces inside empty braces.
  void Reset() { baz_ = 0; }  // Spaces separating braces from implementation.
  ...
void f(bool b) {  // 開き波カッコの前には常にスペースをおく。
  ...

int i = 0;  // セミコロンの前にスペースはおかない。

// 波カッコ初期化子リストの内側はスペースはおいてもおかなくてもよい。
// ただし、スペースをいれる場合は必ず左右の両方におく。
int x[] = { 0 };
int x[] = {0};

// 継承や初期化子のコロンの前後にはスペースをおく。
class Foo : public Bar {
 public:
  // インライン関数の実装において、波カッコと実装の間にはスペースをおく。
  Foo(int b) : Bar(), baz_(b) {}  // 空の実装にはスペースをおかない。
  void Reset() { baz_ = 0; }  // 波カッコと実装との間にはスペースをおく。
  ...

Adding trailing whitespace can cause extra work for others editing the same file, when they merge, as can removing existing trailing whitespace. 行末のスペースは、同じファイルを編集する他の人がマージするときに、行末スペースの削除という余計な仕事を発生させる場合があります。 So: Don't introduce trailing whitespace. このため、行末にスペースを入れてはいけません。 Remove it if you're already changing that line, or do it in a separate clean-up operation (preferably when no-one else is working on the file). もし行末のスペースがある行を編集したときは、そのタイミングで取り除いてください。あるいは、別途コード整理のタイミングで取り除いてください(その場合は、誰もそのファイルを編集していないときがいいでしょう)。

ループと条件式

if (b) {          // Space after the keyword in conditions and loops.
} else {          // Spaces around else.
}
while (test) {}   // There is usually no space inside parentheses.
switch (i) {
for (int i = 0; i < 5; ++i) {
// Loops and conditions may have spaces inside parentheses, but this
// is rare.  Be consistent.
switch ( i ) {
if ( test ) {
for ( int i = 0; i < 5; ++i ) {
// For loops always have a space after the semicolon.  They may have a space
// before the semicolon, but this is rare.
for ( ; i < 5 ; ++i) {
  ...

// Range-based for loops always have a space before and after the colon.
for (auto x : counts) {
  ...
}
switch (i) {
  case 1:         // No space before colon in a switch case.
    ...
  case 2: break;  // Use a space after a colon if there's code after it.
if (b) {          // 条件文やループキーワードの後ろにはスペースをおく。
} else {          // elseの前後にはスペースをおく。
}
while (test) {}   // 丸カッコの内側には通常はスペースをおかない。
switch (i) {
for (int i = 0; i < 5; ++i) {

// ループ文と条件式の丸カッコの内側には、スペースをおいてもかまわないが、
// そのようなケースはほとんどない。周りとの一貫性を保つこと。
switch ( i ) {
if ( test ) {
for ( int i = 0; i < 5; ++i ) {

// ループでは、常にセミコロンの後にスペースをおく。
// セミコロンの前にもスペースをおいてもかまわないが、
// そのようなケースもまたほとんどない。
for ( ; i < 5 ; ++i) {
  ...

// レンジベースのループでは、常にコロンの前後にスペースをおく。
for (auto x : counts) {
  ...
}
switch (i) {
  case 1:         // caseのコロンの前にはスペースをおかない。
    ...
  case 2: break;  // コロンの後ろにコードがある場合はスペースをおく。

演算子

// Assignment operators always have spaces around them.
x = 0;

// Other binary operators usually have spaces around them, but it's
// OK to remove spaces around factors.  Parentheses should have no
// internal padding.
v = w * x + y / z;
v = w*x + y/z;
v = w * (x + z);

// No spaces separating unary operators and their arguments.
x = -5;
++x;
if (x && !y)
  ...
// 代入演算子の前後には常にスペースをおく。
x = 0;

// その他の二項演算子の前後には、通常はスペースをおくが、
// 項の前後のスペースは、適宜削除してもかまわない。
// 丸カッコを使う場合は、その内側にはスペースをおくべきでない。
v = w * x + y / z;
v = w*x + y/z;
v = w * (x + z);

// 単項演算子においては、その引数との間にスペースはおかない。
x = -5;
++x;
if (x && !y)
  ...

テンプレートとキャスト

// No spaces inside the angle brackets (< and >), before
// <, or between >( in a cast
std::vector<string> x;
y = static_cast<char*>(x);

// Spaces between type and pointer are OK, but be consistent.
std::vector<char *> x;
// 山括弧の内側(< and >)にはスペースをおかない。
// キャストにおける<の前や、>(との間にもスペースをおかない。
std::vector<string> x;
y = static_cast<char*>(x);

// ポインタと型名の間のスペースはOK。ただし、周囲との一貫性を保つこと。
std::vector<char *> x;

垂直方向の空白

Minimize use of vertical whitespace. 垂直方向の空白は最低限にしてください。

This is more a principle than a rule: don't use blank lines when you don't have to. これはルールというよりも原則です。不必要な場合は空行を使ってはいけません。 In particular, don't put more than one or two blank lines between functions, resist starting functions with a blank line, don't end functions with a blank line, and be discriminating with your use of blank lines inside functions. 特に、関数と関数との間の空行は1行か2行とし、関数を空行で始めることは控え、関数を空行で終わらせず、関数の中の空行には分別を持ちましょう。

The basic principle is: The more code that fits on one screen, the easier it is to follow and understand the control flow of the program. 基本的な原則は「より多くのコードが1画面内に収まるようにすれば、プログラムのコントロールフローが追いかけやすく理解しやすくなる」というものです。 Of course, readability can suffer from code being too dense as well as too spread out, so use your judgement. もちろん、コードが過剰に密集していると、広がりすぎているのと同じくらい読みにくくなってしまいます。そこは自らの判断に従ってください。 But in general, minimize use of vertical whitespace. ただ、一般的には、縦方向の空白は最低限必要なだけにしてください。

Some rules of thumb to help when blank lines may be useful: 空行の使い方に関する経験則として、次のようなルールが有用かもしれません。

  • Blank lines at the beginning or end of a function very rarely help readability. 関数の最初と最後の空行を入れても、コードが読みやすくなることはまずありません。
  • Blank lines inside a chain of if-else blocks may well help readability. if-elseブロックの連鎖の中に空行を入れると、読みやすくなることがあります。

ルールの例外

The coding conventions described above are mandatory. ここまでに説明したコーディング規約はどれも必須のものです。 However, like all good rules, these sometimes have exceptions, which we discuss here. しかし、すべての良いルールがそうであるように、これらのルールにはいくつかの例外があります。それらをここで議論します。

ルールを満たしていない既存のコード

You may diverge from the rules when dealing with code that does not conform to this style guide. このスタイルガイドのルールを満たしていない既存のコードを扱うときには、このガイドのルールからは外れてかまいません。

If you find yourself modifying code that was written to specifications other than those presented by this guide, you may have to diverge from these rules in order to stay consistent with the local conventions in that code. コードを編集しているとき、元のコードが、本ガイドのルールではなく、別のルールに従っていると気づくことがあるかもしれません。そのような場合には、そのコードの規約との一貫性を保つために、本ガイドのルールからは外れなくてはならないでしょう。 If you are in doubt about how to do this, ask the original author or the person currently responsible for the code. どうしていいか迷った場合、コードの作者や現在の責任者に確認してください。 Remember that consistency includes local consistency, too. 一貫性」には、こういった局所的な一貫性も含まれているということを忘れないでください。

Windowsのコード

Windows programmers have developed their own set of coding conventions, mainly derived from the conventions in Windows headers and other Microsoft code. Windowsプログラマの間では、独自のコーディング規約が開発されてきました。それらは、主にWindowsのヘッダや、その他のMicrosoftのコードのコーディング規約から派生してきたものです。 We want to make it easy for anyone to understand your code, so we have a single set of guidelines for everyone writing C++ on any platform. 我々は、コードが誰にでも簡単に理解されることを望んでおり、そのために、プラットフォームに依存しない、すべてのC++を書く人に向けたただ1つのガイドラインを用意しているのです。

It is worth reiterating a few of the guidelines that you might forget if you are used to the prevalent Windows style: あなたが広く普及しているWindowsルールに馴染んでいるようであれば、よく忘れられがちな以下のガイドラインをおさらいしておきましょう。

  • Do not use Hungarian notation (for example, naming an integer iNum). ハンガリアン記法(たとえば、整数型にiNumと名付ける)は使わないでください。 Use the Google naming conventions, including the .cc extension for source files. ソースコードの拡張子が.ccであることも含め、Googleの命名規則に従ってください。
  • Windows defines many of its own synonyms for primitive types, such as DWORD, HANDLE, etc. Windowsは組み込み型に対する独自のシノニム(同義語)を定義しています(たとえば、DWORDHANDLEなど)。 It is perfectly acceptable, and encouraged, that you use these types when calling Windows API functions. Windows APIを呼び出すときにこれらの型を使用することはまったく問題なく、むしろ推奨されることです。 Even so, keep as close as you can to the underlying C++ types. ただし、その場合であっても、極力、基本的なC++の型から離れないようにしてください。 For example, use const TCHAR * instead of LPCTSTR. たとえば、LPCTSTRではなくconst TCHAR *を使用してください。
  • When compiling with Microsoft Visual C++, set the compiler to warning level 3 or higher, and treat all warnings as errors. コンパイラにMicrosoft Visual C++を使う場合は、コンパイラの警告レベルを3以上に設定し、すべての警告をエラーとして扱うように設定してください。
  • Do not use #pragma once; instead use the standard Google include guards. #pragma onceは使用してはいけません。その代わりに、Google標準のインクルードガードを使用してください。 The path in the include guards should be relative to the top of your project tree. インクルードガードのパスは、プロジェクトツリーのルートからの相対パスを使用します。
  • In fact, do not use any nonstandard extensions, like #pragma and __declspec, unless you absolutely must. #pragma__declspecのような、非標準の拡張は、どうしても必要な場合を除いて使わないでください。 Using __declspec(dllimport) and __declspec(dllexport) is allowed; however, you must use them through macros such as DLLIMPORT and DLLEXPORT, so that someone can easily disable the extensions if they share the code. __declspec(dllimport)__declspec(dllexport)は使っても問題ありません。しかし、その場合であっても必ず、DLLIMPORTDLLEXPORTのようなマクロを通して使わなければいけません。そうしておくことで、他の人が簡単にそのような拡張を無効化することができるようになります。

However, there are just a few rules that we occasionally need to break on Windows: しかし、Windowsにおいては、場合によってルールを曲げなくてはいけないこともあります。

  • Normally we forbid the use of multiple implementation inheritance ; however, it is required when using COM and some ATL/WTL classes. 通常、実装の多重継承は禁止されていますが、COMやATL/WTLクラスを使おうとすると、それが必要になってきます。 You may use multiple implementation inheritance to implement COM or ATL/WTL classes and interfaces. COMやATL/WTLクラスやインターフェースを実装するためであれば、実装の多重継承を使用してもかまいません。
  • Although you should not use exceptions in your own code, they are used extensively in the ATL and some STLs, including the one that comes with Visual C++. 例外は、自分のコードに使うべきではありませんが、ATLやSTLやその他Visual C++からくるコードにおいて広く使われています。 When using the ATL, you should define _ATL_NO_EXCEPTIONS to disable exceptions. ATLを使う場合には、_ATL_NO_EXCEPTIONSを定義して、例外を無効にしてください。 You should investigate whether you can also disable exceptions in your STL, but if not, it is OK to turn on exceptions in the compiler. STLを使う場合は、使用するSTLで例外を無効にできるかどうかを確認し、それができない場合は、例外が使えるようにコンパイラの設定を変更してもかまいません。 (Note that this is only to get the STL to compile. (しかし、例外はSTLをコンパイルするためだけに使用するということに注意してください。 You should still not write exception handling code yourself.) この場合でも、例外を処理するコードを自分で書くべきではありません。)
  • The usual way of working with precompiled headers is to include a header file at the top of each source file, typically with a name like StdAfx.h or precompile.h. プリコンパイル済みヘッダを使ったよくある仕事のやり方は、各ソースファイルの最も先頭で、典型的にはStdAfx.hprecompile.hという名前を持つヘッダファイルをインクルードするというものです。 To make your code easier to share with other projects, avoid including this file explicitly (except in precompile.cc), and use the /FI compiler option to include the file automatically. 明示的にこれをインクルードするようなことは避け、コンパイラオプション/FIを使用して自動的にインクルードするようにしてください(precompile.ccは例外とします)。そうすることによって、他のプロジェクトとコードを共有しやすくすることができます。
  • Resource headers, which are usually named resource.h and contain only macros, do not need to conform to these style guidelines. リソースヘッダ(通常はresource.hという名前を持ち、マクロのみを含んでいるファイル)はこのルールに従う必要はありません。

Use common sense and BE CONSISTENT. 常識を大切にし、一貫性を持ってください

If you are editing code, take a few minutes to look at the code around you and determine its style. コードを編集する前には、1~2分、コード全体を眺める時間をとって、そのコードの持つスタイルを判別してください。 If they use spaces around their if clauses, you should, too. ifの周りにスペースがあったら、あなたもそのようにします。 If their comments have little boxes of stars around them, make your comments have little boxes of stars around them too. コメントがアスタリスクで囲まれた箱になっていたら、あなたのコメントもアスタリスクで囲って箱にしましょう。

The point of having style guidelines is to have a common vocabulary of coding so people can concentrate on what you are saying, rather than on how you are saying it. スタイルガイドラインを持つことの要点は、コーディングにおける共通のボキャブラリを持つということです。これによって、みんなが、どう話すかという話し方ではなく、何を話すかという話の内容に集中できるようになるのです。 We present global style rules here so people know the vocabulary. 我々はここでグローバルなスタイルルールを説明しています。これによって、みんなが、共通のボキャブラリを持つことができます。 But local style is also important. しかし、ローカルなスタイルもまた重要なものです。 If code you add to a file looks drastically different from the existing code around it, the discontinuity throws readers out of their rhythm when they go to read it. もし、あなたがファイルに追加したコードが、その周囲の既存のコードと大きく違って見えてしまうと、その境目によっ読者のリズムを崩してしまいます。 Try to avoid this. これを避けるよう努めましょう。

OK, enough writing about writing code; the code itself is much more interesting. よし、コードを書くことについて書くのはもう十分でしょう。コードそのものを書くほうがもっとずっと面白いです。 Have fun! 楽しんでください!