0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Google C++ Style Guideを読む3~Google特殊のマジック・その他のC++の機能~

Last updated at Posted at 2025-12-23

初めに

Google C++ Style Guide
ライセンスCC-By 3.0 License


ttsukiさんの日本語訳
ライセンスCC-By 3.0 License


初回の記事

前回の記事


Google-Specific Magic

この章では、Googleがコードをより堅牢にするために使用しているトリックやユーティリティが紹介されている。

Ownership and Smart Pointers

動的確保されたオブジェクトは単一で固定された所有者(そレを行うコード)に属するようにする。その他の場所からアクセスする場合には、コピーもしくはポインタか参照を渡す方法をもいいる。

オブジェクトの所有権を移すときにはスマートポインタ(std::unique_ptr)を使用する。

所有権はなるべく共有させるべきでない。
共有する場合は、パフォーマンス上のメリットが非常に高いことと、対象のオブジェクトがconstで有ることが必要。
その際はstd::shared_ptrを使用する。

なおstd::auto_ptrの使用は禁止

cpplint

cpplint.pyを使用する。
行末に// NOLINTまたは、直前の行に// NOLINTNEXTLINEを記述することで、リンターに無視させることができる。

追記: 使用方法
cpplint.pyを作成
上のリンクのコードをコピー、貼り付け
pythonで実行

Other C++ Features

Rvalue References

右辺地参照は以下の場合に限り使用可能

  • ムーブコンストラクタ、ムーブ代入演算子を定義するため
  • *thisを消費し、それ以降使用不可にするメソッドを定義するため
  • perfect firwardubgを実現するため
  • オーバーロードの組を定義する場合

Friend

明確な理由がある場合はfriendクラス/関数は使用可能。

通常、friendに指定する対象は同じファイル内で定義する。
ただし、原則としてクラス同士のやり取りはpublicメンバを通して行う。

noexcept

有用かつ正しい場合にnoexceptを指定する。
パフォーマンスが向上する場合など。

例外を完全に無効にしている環境では条件なしnoexceptを使用する。
それ以外の場合には条件付きで使用する。

備考
Googleは既存のコードとの互換性のためにC++の例外の使用を禁止している。
この章の前にExceptionsについて説明している章があるが、例外を禁止にしている理由が互換性のためだけなので省略した。本文

Run-Time Type Information (RTTI)

実行時にオブジェクトのC++クラスを調べるRTTIで型を調べようとせずに、仮想関数を用いたり、Visitorデザインパターンなどで未然に防ぐほうが良い。

型による分岐が必要な場合は設計を変更するべきである。

Casting

static_castといったC++のキャストを使用する。
算術型の変換には{}を用いた初期化を使用する。

- (int)x // void型へのキャストのみ使用可能
+ static_cast<float>(double_value)
+ int64_t y = int64_t{1} << 42
+ T(x)  // 型Tがクラスの場合は使用可能

constを外す場合はconst_cast
ポインタ型と整数型のような安全でない変換にはreinterpret_cast
ビット列を違う型として使用するときにはstd::bit_castを使用する。

Stream

シンプルかつ適切な場合に限りストリームを使用できる。

<<のオーバーロードは、その型オブジェクトが何らかの値を表す場合のみ行う。
内部状態をデバッグする目的にはDebugString()などのメンバ関数を作成した方がよい。

Preincrement and Predecrement

可能な限り、前置インクリメント/デクリメントを用いる。

Use of const

可能ならば常にconstを用いる。
加えてconstexprの方が適切な場合もある。

ただし、値渡し関数の引数では、呼び出し側に影響を与えないため、constでの関数宣言は非推奨。

Where to put the const

基本的にはconst intのように前置する形を推奨する。

Use of constexpr

定数初期化の保証にはconstexprを使用する。
非定数変数に対して定数初期化を保証するときにconstinitを使用する。

Integer Types

基本的にint型のみを使用する。
異なるサイズの整数値を使用する場合はstdint.hよりint64_tのようなサイズが厳密に定められた整数型を使用する。

また、サイズに疑問がある場合はより大きな型を使用するべき。

unsignedは、正当な理由がなければ使用禁止。
ここでの理由は、ビットパターンを表している場合や余剰によるオーバーフロー時の動作定義など。
負にならないことを示すときにはassertを使用する。

Floating-Point Types

floatdoubleのみを使用する。
これらはIEEE-754binary32/binary64を表すものとして良い。

long doubleは環境依存なので使用不可。

Architecture Portability

環境依存のコードは書かず、移植性を確保する。

print系ではなくabsol::StrCatstd::ostreamなど、型安全に数値型のフォーマットを行えるライブラリをしよう
する。

メモリアドレスを整数として扱う場合はuintptr_tを用いる。
...など。

Preprocessor Macro

マクロを定義しない。変わりに列挙型やconst変数を用いる。
これは、画面上のコードとコンパイラの見るコードが異なってしまうからである。

もしマクロを使用する場合には、

  • .hファイル内で定義しない
  • 使う直前に#defineし、使用後すぐに#undef
  • 既存のマクロを置き換えず、ユニークな名前を使用する
  • 関数名やクラス名を生成するために##を使用しない

0 and nullptr/NULL

ポインタにはnullptr、文字には'\0'を使用する(0は使用しない)。

sizeof

sizeof(型)よりもsizeof(変数名)を使用する。

Type Deduction (including auto)

型推論は、可読性の大きな向上が期待できる場合と、コードが安全にできる場合に限り使用する。

Function template argument deducion

関数テンプレートの仕様は問題ない。むしろ通常の仕様方法である。

Local variable type deduction

ローカル変数の型推論は、コードをより明確にできる場合がある。

decltype(auto)は、他の方法では実装不可能な場合のみ使用する。

Return type deduction

戻り値の型推論は、その関数に含まれるreturn文の数が非常に少なく、また他のコードにより型を判断できる(シンプル)場合にのみ使用する。

ただしヘッダーファイル内の関数は戻り値の型推論を行うべきでない。

Parameter type deduction

ラムダ式の引数をautoにした場合は、呼び出しもとのコードによって型が決定される。
よって引数の型推論は、宣言と呼び出し元が十分に近く、型を用意に想像可能な場合のみに使用する。

Class Template Argument Deduction

クラステンプレートのテンプレート引数推論は明確な推論ガイドが提供されている場合にのみ使用する。
なお、std名前空間のテンプレートはすべてこれに対応しているものとする。

Designated Initializers

指示付き初期化演算子はC++20標準に順する形式でのみ使用する。

Lambda expressions

ラムダ式は匿名関数オブジェクトを作るための簡潔な手段である。

ラムダ式は以下の書式に従う。
参照キャプチャ[&]はラムダの寿命が明らかに短い場合にのみ使用する。

Template metaprogramming

複雑なテンプレートの使用は避ける。

テンプレートメタプログラミングを用いる場合、その複雑さを最小限に保ち、また適切なコメントをするなどしてコードの可読性を高めると同時に、エラーメッセージを適切に生成するようにする。

Concepts and Constraints

コンセプトは控えめに。

型トレイトと同様のコンセプトでは、コンセプトを使用する。

また、template<Concept T>よりもrequires(Concept<T>)の構文を使用する。

C++20 modules

C++20のモジュールは使用しない。

Coroutines

プロジェクト全体で共有されたコルーチンライブラリのみ使用する。

Boost

以下のライブラリを使用できる。

  • Call Traits (boost/call_traits.hpp)
  • Compressed Pair (boost/compressed_pair.hpp)
  • The Boost Graph Library (BGL) (boost/graph) ただし、serialization (adj_list_serialize.hpp)と、 parallel/distributed algorithms and data structures (boost/graph/parallel/, boost/graph/distributed/)を除く
  • Property Map(boost/property_map) ただし、parallel/distributed property maps (boost/property_map/parallel/*) を除く
  • Iterator (boost/iterator)
  • Polygonのうち、Voronoi diagram constructionを扱い、かつ残りのPolygonに依存していない部分 (boost/polygon/voronoi_builder.hpp, boost/polygon/voronoi_diagram.hpp, boost/polygon/voronoi_geometry_type.hpp)
  • Bimap (boost/bimap)
  • Statistical Distributions and Functions (boost/math/distributions)
  • Special Functions (boost/math/special_functions)
  • Root Finding & Minimization Functions (boost/math/tools)
  • Multi-index (boost/multi_index)
  • Heap (boost/heap)
  • ContainerのThe flat containers (boost/container/flat_map, boost/container/flat_set)
  • Intrusive (boost/intrusive)
  • The boost/sort library
  • Preprocessor (boost/preprocessor)

Disallowed standard library features

以下のライブラリ機能は使用禁止。

  • <ration>
  • <cfenv>
  • <fenv.h>
  • <filesystem>

Nonstandart Extensions

C++非標準の拡張は使用禁止。

Aliases

APIの公開で、クライアントが使用することを前提としたエイリアスのみを定義する。

名前空間へのエイリアスを公開してはいけない。

Switch Statements

列挙型以外のswitch文はdefaultチェックが必要である。

他のケースへのフォールスルーには[[fallthrough]];属性が必要。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?