この記事では、主にこれまで C++ に触れたことがない人に向けて、C++の開発がどのような空気感を持っているのかを紹介したいと思います。
背景
知人から「仕事で C++ を触ることになりそうだ」という話を聞きました。彼は現在 Python での開発をメインにしており、他に C# の経験はあるものの、 C/C++ は初めてとのことでした。
その流れで、「ライブラリの管理はどうしてるの?」と聞かれました。私はこの問いに対し「チームによるし、正直何とも言えない」と答えました。この答えは C++ 開発者であれば納得できるものかと思いますが、一方で Python のようにエコシステムが整備された言語に慣れている人からすると、不思議に感じるだろうなと思いました。
この会話がきっかけで、C++ 開発者の立場から、C++ の開発がどのような感じなのかを書いてみようと思いました。
伝えたいこと
歴史的な経緯もあり、C++は開発コミュニティごとの違いが大きく、「標準的なやり方」が少ない言語です。システムプログラミングの分野で重要な役割を果たしてきた言語であるがゆえに、Windows と Unix のそれぞれで独自に発展し、ビルド環境やツールチェーン、慣習といった面で長らく分断された状態が続いてきました。
今でこそ状況は改善されていますが、それでもなお、C++が歴史的な課題を背負った言語であることは否めません。そしてそれは、他の言語をメインに使っている人には意外と伝わりづらい部分でもあります。
こういった C++ 特有の感覚を伝えたい、というのがこの記事の趣旨です。
パッケージマネージャー
C++ には pip や NuGet のような標準的なパッケージマネージャーがありません。最近は Conan や vcpkg といったツールが登場しているものの、これらを使わない人も多いのが現状です。
参考として、標準C++財団による2025年の調査結果を引用します。この組織では C++ 開発者への調査を毎年行っており、質問項目として「ライブラリを管理をどうしているか?」というものがあります。その回答が以下の通りです。
出典: https://isocpp.org/files/papers/CppDevSurvey-2025-summary.pdf
合計が100%を越えているのは重複回答ありのためです。
1位が「ライブラリのソースコードを自分達のコードと一緒にビルドしている」、2位が「手順に従ってライブラリをビルドして使っている」、3位に「システムのパッケージマネージャー (apt や brew) を使う」が来ます。パッケージマネージャー (Conan) が登場するのは 4 位で、その割合は 23% 程度です。
他の言語でいえば「pipを使っている」や「NuGetを使っている」「npmを使っている」などの回答が2割しかない、みたいな話です。マジかよ、と思うかもしれません。
C++はライブラリの利用がコンパイラやビルド設定と強く結びついており、「パッケージを取得する」ことと「正しくビルドする」ことを切り離しにくい、という事情があります。
Conan や vcpkg はこういった問題を解決するためのツールなのですが、これらはビルドツールに標準付属するものではありません。ライブラリを管理するために外部のツールを導入し、その使い方を覚えるというのはそれなりにハードルが高いものです。それよりはソースコードをコピーして (あるいは git submodule して) 持ってくる方が手っ取り早い、という考えになりがちです。
命名規約やスタイル
現在使われる言語の多くは命名やコーディングスタイルが確立しており、多少のバリエーションはあれど、コードの見た目はそこまで違わないと思います。ですが C++ では、開発者や組織によって書き方はだいぶ異なります。
こういった話は宗教戦争になりがちなので、こだわりすぎない方が良いと思います。「どちらが正しい」ではなく、スタイルが異なるだけです。チームに規約がある場合は、それに従うのがベターでしょう。
拡張子
「えっ?」と思うかもしれませんが、実は C++ のソースコードはどのような拡張子でも構いません。ビルドツールは渡されたファイルをコンパイルするだけなので、ファイル名が file.cpp だろうと file.txt だろうと、同じように動作します 1。
C++ のコードにはヘッダーファイルとソースファイルというものがあり、一般的には以下の拡張子が使われす。
ソースファイル: .cpp, .cc, .cxx
ヘッダーファイル: .h, .hpp, .hh, .hxx
これらの違いは文化的なものであり、「これが正しい」というものはありません。どれも実際に使われます。
コーディングスタイル
C++ では公式や準公式相当の命名規約やスタイル規約はありません。例えば標準ライブラリではクラスや関数の名前を全て snake_case で統一していますが、 Google のコーディングガイドでは「クラス名は PascalCase, 関数やメソッドは camelCase」、 Microsoftでは「クラス名も関数名も PascalCase」のように、組織によってまちまちです。Python のように「クラスは PascalCase, 関数やメソッドは snake_case」という人も多いです。
例えば Microsoft と Google のスタイルを比べると、以下のようになります。
// Microsoft のスタイル
// - 関数は PascalCase
// - インデントは4スペース
// - 括弧の前後で改行する
if (condition)
{
DoWork();
}
else
{
DoAnotherWork();
}
// Google のスタイル
// - 関数は camelCase
// - インデントは2スペース
// - 開き括弧の前で改行しない
if (condition) {
doWork();
} else {
doAnotherWork();
}
ポインタの前に付けるアスタリスクの位置も、派閥が分かれます 2。
// 型に寄せる派 (Google や Mozilla)
int* ptr = &value;
// 変数に寄せる派 (LLVM)
int *ptr = &value;
これらに正解はありません。プロジェクト内での一貫性は保つ方が良いですが、こだわり過ぎる必要はないと思います。
言語バージョン
他の言語と同様、 C++ の仕様も年々進化しています。ですが C++ は最新の機能をすぐに使えるわけではありません。
Python や C# では、言語の仕様を決める組織自身が公式の実装を公開しています。そのため、「言語の新しいバージョンがリリースされた」というのは、その時点でそれが使えることを意味します。 2025 年には Python 3.14 や C# 14 が出ましたし、 2026 年内には Python 3.15 や C# 15 が使えるようになるでしょう。
一方 C++ は、言語仕様の作成は委員会方式で進められており、その内容を元に各ベンダーがコンパイラの実装を行います。そのため、言語仕様が策定された時点でそれが使える、とはならないものです。実装状況はコンパイラによって異なり、例えば「Microsoftのコンパイラは C++23 のこの機能には対応しているが、この機能はまだ使えない」といったことが起こります。
参考までに、 C++ のバージョンについて説明します。現在の C++ は3年ごとに仕様が策定され、その年の下2桁がバージョン名になります。 2011年に C++11, 2014年に C++14 といった具合です。現在の最新は C++23 で、 2026年には C++26 が策定される予定です。
実際にどのバージョンを使えるかはプロジェクトにもよります。最近は C++17 くらいは使えるところが多いと思いますが、 C++11 や C++14 を使っているというプロジェクトもあるでしょう。先ほども引用した2025年の開発者調査では、以下のような結果となっていました。
Python だと、2020年にリリースされた Python 3.9 は2025年にサポートが切れました。それと比較すると、同年に出た C++20 がまだ浸透しきっていない 3 というのは、時間感覚にだいぶ違いがあると感じるかもしれません。
終わりに
ここまでいろいろと書いてきましたが、いかがでしょうか。Python などの言語と比べると、C++ の開発まわりはあまり整備されていないな、と感じるかもしれません。
ですが、こうした点も実際の開発では、プロジェクトごとに方針が決まってしまえば、日々悩み続けるものではありません。ライブラリの管理やコーディングスタイルについて考える時間よりも、言語の機能を学んだり、コードを書いたりする時間の方がずっと多くなっていきます。そうして開発を続けるうちに、C++ 特有の文化や前提にも自然と慣れていくはずです。
C++ とはそういう言語なんだな、という感覚が少しでも伝われば幸いです。
-
IDEやエディタは「一般的な C++ の拡張子であればシンタックスハイライトを行う」ようになっているので、変な拡張子にはしない方が良いです。 ↩
-
インデントや改行は見た目だけの違いですが、アスタリスクの位置には開発者の考え方の違いが表れることがあります。
int* ptrと書く人は「int*型の変数ptr」のように捉え、int *ptrと書く人は「ptrの参照先がint」のように捉えているように思います。 ↩ -
C++20 は比較的大きな変更が入ったバージョンである、というのも理由の一つだと思います。標準ライブラリに追加された便利な機能 (std::format など) は使うけど、構文が大きく変わる・コンパイラによる実装状況に差がある機能はまだ使わない、という開発者が多いと思います。 ↩

