Communitygithub.com

C++ コーディング規約(C++ Core Guidelines)

C++ Core Guidelines (isocpp.github.io) に基づいたC++コーディング規約です。C++コードの作成、レビュー、リファクタリング時に使用し、モダンで安全かつ慣用的なプラクティスを強制します。

C++ コーディング規約(C++ Core Guidelines) とは?

このスキルは、C++ Core Guidelines に基づいた包括的なコーディング規約を提供します。C++17/20/23 を対象とし、型安全性、リソース安全性、不変性、明確性を重視します。新しいC++コードの作成、既存コードのレビューやリファクタリング、アーキテクチャ上の意思決定、コードベース全体での一貫したスタイルの強制など、様々な場面で活用できます。RAII、不変性のデフォルト設定、値セマンティクスなどの基本原則から、関数、クラス、リソース管理、エラー処理、並行性に至るまで、主要なガイドラインルールをコード例とともに整理しています。各ルールには「すべきこと」と「すべきでないこと」が明確に示され、実践的な適用が容易です。プラットフォームに依存せず、あらゆるC++開発環境で利用できます。

対応~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/everything-claude-code/tree/main/skills/cpp-coding-standards

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

C++ コーディング規約(C++ Core Guidelines) は何をしますか?

C++ Core Guidelines に基づいた、モダンなC++(C++17/20/23)向けの包括的なコーディング規約です。型安全性、リソース安全性、不変性、明確性を強制します。

使用するタイミング

  • 新しいC++コード(クラス、関数、テンプレート)を作成するとき
  • 既存のC++コードをレビューまたはリファクタリングするとき
  • C++プロジェクトでアーキテクチャ上の意思決定を行うとき
  • C++コードベース全体で一貫したスタイルを強制するとき
  • 言語機能(例:enum vs enum class、生ポインタ vs スマートポインタ)を選択するとき

使用すべきでないタイミング

  • C++以外のプロジェクト
  • モダンなC++機能を採用できないレガシーなCコードベース
  • 特定のガイドラインがハードウェアの制約と矛盾する組み込み/ベアメタル環境(選択的に適応してください)

横断的な原則

これらのテーマはガイドライン全体に繰り返し登場し、基礎を形成します。

  1. RAIIをあらゆる場所で (P.8, R.1, E.6, CP.20): リソースのライフタイムをオブジェクトのライフタイムにバインドする
  2. デフォルトで不変性を (P.10, Con.1-5, ES.25): const/constexpr から始め、可変性は例外とする
  3. 型安全性 (P.4, I.4, ES.46-49, Enum.3): 型システムを使用してコンパイル時にエラーを防止する
  4. 意図を表現する (P.3, F.1, NL.1-2, T.10): 名前、型、概念は目的を伝えるべきである
  5. 複雑性を最小化する (F.2-3, ES.5, Per.4-5): シンプルなコードは正しいコードである
  6. ポインタセマンティクスよりも値セマンティクスを優先する (C.10, R.3-5, F.20, CP.31): 値での返却とスコープ付きオブジェクトを優先する

設計思想 & インターフェース (P., I.)

主要ルール

ルール概要
P.1アイデアをコードで直接表現する
P.3意図を表現する
P.4理想的には、プログラムは静的に型安全であるべき
P.5実行時チェックよりもコンパイル時チェックを優先する
P.8リソースを漏らさない
P.10可変データよりも不変データを優先する
I.1インターフェースを明示的にする
I.2非constなグローバル変数を避ける
I.4インターフェースを正確かつ強く型付けする
I.11所有権を生ポインタや参照で決して転送しない
I.23関数の引数の数を少なく保つ

すべきこと

// P.10 + I.4: 不変で、強く型付けされたインターフェース
struct Temperature {
    double kelvin;
};

Temperature boil(const Temperature& water);

すべきでないこと

// 弱いインターフェース: 所有権が不明確、単位が不明確
double boil(double* temp);

// 非constなグローバル変数
int g_counter = 0;  // I.2 違反

関数 (F.*)

主要ルール

ルール概要
F.1意味のある操作を注意深く名前付けされた関数にまとめる
F.2関数は単一の論理操作を実行すべき
F.3関数を短くシンプルに保つ
F.4関数がコンパイル時に評価される可能性がある場合は、constexpr として宣言する
F.6関数が例外をスローしてはならない場合は、noexcept として宣言する
F.8純粋関数を優先する
F.16「入力」パラメータには、コピーが安価な型は値で、その他は const& で渡す
F.20「出力」値には、出力パラメータよりも戻り値を優先する
F.21複数の「出力」値を返すには、構造体を返すことを優先する
F.43ローカルオブジェクトへのポインタや参照を決して返さない

パラメータの渡し方

// F.16: 安価な型は値で、その他は const& で
void print(int x);                           // 安価: 値渡し
void analyze(const std::string& data);       // 高価: const& で
void transform(std::string s);               // シンク: 値で(ムーブされる)

// F.20 + F.21: 出力パラメータではなく戻り値を使用
struct ParseResult {
    std::string token;
    int position;
};

ParseResult parse(std::string_view input);   // 良い: 構造体を返す

// 悪い: 出力パラメータ
void parse(std::string_view input,
           std::string& token, int& pos);    // これは避ける

純粋関数と constexpr

// F.4 + F.8: 可能な限り純粋で constexpr に
constexpr int factorial(int n) noexcept {
    return (n <= 1) ? 1 : n * factorial(n - 1);
}

static_assert(factorial(5) == 120);

アンチパターン

  • 関数から T&& を返す(F.45)
  • va_arg / Cスタイルの可変長引数を使用する(F.55)
  • 他のスレッドに渡されるラムダで参照でキャプチャする(F.53)
  • ムーブセマンティクスを阻害する const T を返す(F.49)

クラス & クラス階層 (C.*)

主要ルール

ルール概要
C.2不変条件が存在する場合は class を、データメンバが独立して変化する場合は struct を使用する
C.9メンバの露出を最小限にする
C.20デフォルト操作の定義を避けられるなら、そうする(ゼロのルール)
C.21コピー/ムーブ/デストラクタを定義または =delete する場合は、すべてを処理する(5つのルール)
C.35基底クラスのデストラクタ: public virtual または protected non-virtual
C.41コンストラクタは完全に初期化されたオブジェクトを作成すべき
C.46単一引数のコンストラクタは explicit として宣言する
C.67ポリモーフィックなクラスは public なコピー/ムーブを抑制すべき
C.128仮想関数: virtual、override、final のうち正確に1つを指定する

ゼロのルール

// C.20: コンパイラに特殊メンバを生成させる
struct Employee {
    std::string name;
    std::string department;
    int id;
    // デストラクタ、コピー/ムーブコンストラクタ、代入演算子は不要
};

5つのルール

// C.21: リソースを管理する必要がある場合は、5つすべてを定義する
class Buffer {
public:
    explicit Buffer(std::size_t size)
        : data_(std::make_unique<char[]>(size)), size_(size) {}

    ~Buffer() = default;

    Buffer(const Buffer& other)
        : data_(std::make_unique<char[]>(other.size_)), size_(other.size_) {
        std::copy_n(other.data_.get(), size_, data_.get());
    }

    Buffer& operator=(const Buffer& other) {
        if (this != &other) {
            auto new_data = std::make_unique<char[]>(other.size_);
            std::copy_n(other.data_.get(), other.size_, new_data.get());
            data_ = std::move(new_data);
            size_ = other.size_;
        }
        return *this;
    }

    Buffer(Buffer&&) noexcept = default;
    Buffer& operator=(Buffer&&) noexcept = default;

private:
    std::unique_ptr<char[]> data_;
    std::size_t size_;
};

クラス階層

// C.35 + C.128: 仮想デストラクタ、override を使用
class Shape {
public:
    virtual ~Shape() = default;
    virtual double area() const = 0;  // C.121: 純粋インターフェース
};

class Circle : public Shape {
public:
    explicit Circle(double r) : radius_(r) {}
    double area() const override { return 3.14159 * radius_ * radius_; }

private:
    double radius_;
};

アンチパターン

  • コンストラクタ/デストラクタ内で仮想関数を呼び出す(C.82)
  • 非トリビアル型に対して memset/memcpy を使用する(C.90)
  • 仮想関数とオーバーライダーで異なるデフォルト引数を提供する(C.140)
  • データメンバを const や参照にすると、ムーブ/コピーが抑制される(C.12)

リソース管理 (R.*)

主要ルール

ルール概要
R.1RAII を使用してリソースを自動的に管理する
R.3生ポインタ (T*) は非所有とする
R.5スコープ付きオブジェクトを優先する; 不必要にヒープ割り当てをしない
R.10malloc()/free() を避ける
R.11new と delete を明示的に呼び出すことを避ける
R.20所有権を表現するために unique_ptr または shared_ptr を使用する
R.21所有権を共有しない限り、shared_ptr よりも unique_ptr を優先する
R.22shared_ptr を作成するには make_shared() を使用する

スマートポインタの使用法

// R.11 + R.20 + R.21: スマートポインタによるRAII
auto widget = std::make_unique<Widget>("config");  // 一意な所有権
auto cache  = std::make_shared<Cache>(1024);        // 共有所有権

// R.3: 生ポインタ = 非所有の観察者
void render(const Widget* w) {  // w を所有しない
    if (w) w->draw();
}

render(widget.get());

RAII パターン

// R.1: リソースの取得は初期化である
class FileHandle {
public:
    explicit FileHandle(const std::string& path)
        : handle_(std::fopen(path.c_str(), "r")) {
        if (!handle_) throw std::runtime_error("Failed to open: " + path);
    }

    ~FileHandle() {
        if (handle_) std::fclose(handle_);
    }

    FileHandle(const FileHandle&) = delete;
    FileHandle& operator=(const FileHandle&) = delete;
    FileHandle(FileHandle&& other) noexcept
        : handle_(std::exchange(other.handle_, nullptr)) {}
    FileHandle& operator=(FileHandle&& other) noexcept {
        if (this != &other) {
            if (handle_) std::fclose(handle_);
            handle_ = std::exchange(other.handle_, nullptr);
        }
        return *this;
    }

private:
    std::FILE* handle_;
};

アンチパターン

  • 裸の new/delete(R.11)
  • C++コードでの malloc()/free()(R.10)
  • 単一の式での複数のリソース割り当て(R.13 -- 例外安全性の危険)
  • unique_ptr で十分な場合の shared_ptr(R.21)

式 & 文 (ES.*)

主要ルール

ルール概要
ES.5スコープを小さく保つ
ES.20オブジェクトは常に初期化する
ES.23{} 初期化構文を優先する
ES.25変更が意図されていない限り、オブジェクトを const または constexpr として宣言する
ES.28const 変数の複雑な初期化にはラムダを使用する
ES.45マジック定数を避ける; シンボリック定数を使用する
ES.46幅を狭める/精度が失われる算術変換を避ける
ES.470 や NULL ではなく nullptr を使用する
ES.48キャストを避ける
ES.50const をキャストして外さない

初期化

// ES.20 + ES.23 + ES.25: 常に初期化し、{} を優先し、デフォルトで const にする
const int max_retries{3};
const std::string name{"widget"};
const std::vector<int> primes{2, 3, 5, 7, 11};

// ES.28: 複雑な const 初期化のためのラムダ
const auto config = [&] {
    Config c;
    c.timeout = std::chrono::seconds{30};
    c.retries = max_retries;
    c.verbose = debug_mode;
    return c;
}();

アンチパターン

  • 初期化されていない変数(ES.20)
  • ポインタとして 0 や NULL を使用する(ES.47 -- nullptr を使用)
  • Cスタイルのキャスト(ES.48 -- static_cast、const_cast などを使用)
  • const をキャストして外す(ES.50)
  • 名前付き定数なしのマジックナンバー(ES.45)
  • signed と unsigned の算術演算を混在させる(ES.100)
  • ネストされたスコープで名前を再利用する(ES.12)

エラー処理 (E.*)

主要ルール

ルール概要
E.1設計の初期段階でエラー処理戦略を策定する
E.2関数が割り当てられたタスクを実行できないことを通知するために例外をスローする
E.6RAII を使用してリークを防止する
E.12スローが不可能または受け入れられない場合は noexcept を使用する
E.14目的に応じて設計されたユーザー定義型を例外として使用する
E.15値でスローし、参照でキャッチする
E.16デストラクタ、デアロケーション、および swap は決して失敗してはならない
E.17すべての関数ですべての例外をキャッチしようとしない

例外階層

// E.14 + E.15: カスタム例外型、値でスロー、参照でキャッチ
class AppError : public std::runtime_error {
public:
    using std::runtime_error::runtime_error;
};

class NetworkError : public AppError {
public:
    NetworkError(const std::string& msg, int code)
        : AppError(msg), status_code(code) {}
    int status_code;
};

void fetch_data(const std::string& url) {
    // E.2: 失敗を知らせるためにスロー
    throw NetworkError("connection refused", 503);
}

void run() {
    try {
        fetch_data("https://api.example.com");
    } catch (const NetworkError& e) {
        log_error(e.what(), e.status_code);
    } catch (const AppError& e) {
        log_error(e.what());
    }
    // E.17: ここではすべてをキャッチしない -- 予期しないエラーは伝搬させる
}

アンチパターン

  • int や文字列リテラルなどの組み込み型をスローする(E.14)
  • 値でキャッチする(スライシングのリスク)(E.15)
  • エラーを静かに飲み込む空のキャッチブロック
  • フロー制御に例外を使用する(E.3)
  • errno のようなグローバル状態に基づくエラー処理(E.28)

定数 & 不変性 (Con.*)

全ルール

ルール概要
Con.1デフォルトでは、オブジェクトを不変にする
Con.2デフォルトでは、メンバ関数を const にする
Con.3デフォルトでは、ポインタと参照を const に渡す
Con.4構築後に変更されない値には const を使用する
Con.5コンパイル時に計算可能な値には constexpr を使用する
// Con.1 から Con.5: デフォルトで不変性を
class Sensor {
public:
    explicit Sensor(std::string id) : id_(std::move(id)) {}

    // Con.2: デフォルトで const メンバ関数
    const std::string& id() const { return id_; }
    double last_reading() const { return reading_; }

    // 変更が必要な場合のみ非 const
    void record(double value) { reading_ = value; }

private:
    const std::string id_;  // Con.4: 構築後は決して変更されない
    double reading_{0.0};
};

// Con.3: const 参照で渡す
void display(const Sensor& s) {
    std::cout << s.id() << ": " << s.last_reading() << '\n';
}

// Con.5: コンパイル時定数
constexpr double PI = 3.14159265358979;
constexpr int MAX_SENSORS = 256;

並行性 & 並列処理 (CP.*)

主要ルール

ルール概要
CP.2データ競合を避ける
CP.3書き込み可能なデータの明示的な共有を最小化する
CP.4スレッドではなくタスクの観点で考える
CP.8同期に volatile を使用しない
CP.20RAII を使用し、決して裸の lock()/unlock() を使用しない
CP.21複数のミューテックスを取得するには std::scoped_lock を使用する
CP.22ロックを保持している間は未知のコードを決して呼び出さない
CP.42条件なしで待機しない
CP.44lock_guard と unique_lock に名前を付けることを忘れない
CP.100絶対に必要でない限り、ロックフリープログラミングを使用しない

安全なロック

// CP.20 + CP.44: RAII ロック、常に名前付き
class ThreadSafeQueue {
public:
    void push(int value) {
        std::scoped_lock lock(mutex_);  // CP.21: 複数ミューテックスも安全
        data_.push(value);
    }

    bool pop(int& value) {
        std::scoped_lock lock(mutex_);
        if (data_.empty()) return false;
        value = data_.front();
        data_.pop();
        return true;
    }

private:
    std::queue<int> data_;
    mutable std::mutex mutex_;
};

アンチパターン

  • 同期に volatile を使用する(CP.8)
  • 裸の lock()/unlock() ペア(CP.20 -- 代わりに scoped_lock を使用)
  • ロックを保持したまま未知のコードを呼び出す(CP.22 -- デッドロックのリスク)
  • 条件変数なしでビジーループ(CP.42 -- condition_variable を使用)
  • 適切なケースなしでのロックフリーデータ構造の使用(CP.100)
  • std::async からの未来を無視する(CP.25 -- これはブロッキング破棄を引き起こす)

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

関連スキル