C++のバージョンの違いについて

AI実装検定のご案内

目次

C++のバージョンとは?

C++には、C++98、C++03、C++11、C++14、C++17、C++20、C++23など、複数の言語規格があります。

ここでいう「C++のバージョン」は、単なるコンパイラソフトの新旧ではなく、どのC++規格の文法や標準ライブラリを使用するかを表すものです。

2026年8月時点で、正式に公開されている最新のC++標準はC++23です。

一方、その次にあたるC++26は策定が進められている段階で、GCCやClangなど一部のコンパイラでは、正式標準化前の機能を先行して利用できます。

C++規格とコンパイラのバージョンは別物

C++について理解するときに、特に重要なのが「C++規格」と「コンパイラのバージョン」を区別することです。

たとえば、次のような表記があります。

C++17
C++20
C++23

これらはC++の言語規格です。

一方で、

GCC 15
Clang 20
Visual Studio 2022
MSVC

などはコンパイラや開発環境の種類・バージョンを表します。

イメージとしては、次のような関係です。

C++規格
├─ C++17
├─ C++20
└─ C++23

コンパイラ
├─ GCC
├─ Clang
└─ MSVC

新しいバージョンのコンパイラをインストールしたからといって、自動的に最新のC++規格でコンパイルされるとは限りません。

使用する規格は、コンパイルオプションや開発環境の設定によって指定できます。

C++98とは?

C++98は、1998年に最初のISO標準として制定されたC++規格です。

現在でも基本となっている、

std::vector
std::string
std::map

などの標準ライブラリは、この時代から利用されています。

一方で、現在のC++でよく使われる、

auto
nullptr
ラムダ式
range-based for
スマートポインタ

などの機能はまだありませんでした。

現在、新しく開発を始める場合にC++98を選択するケースは限定的です。

既存の古いシステムや、古いコンパイラとの互換性を維持する必要がある場合などに使われることがあります。


C++03とは?

C++03は、C++98を修正・改善した規格です。

C++11のように多数の新機能を導入した大型アップデートではなく、C++98で見つかった問題点の修正や仕様の明確化が中心となっています。

そのため、C++98とC++03をまとめて旧来のC++として扱うこともあります。

C++11とは?

C++11は、C++の歴史において非常に大きな転換点となった規格です。

現在一般的に「Modern C++」と呼ばれるプログラミングスタイルの基礎となる機能が多数追加されました。

autoが使いやすくなった

C++11では、変数の型をコンパイラに推論させるautoが大幅に使いやすくなりました。

従来は、

std::vector<int>::iterator it = numbers.begin();

のように長い型名を書く必要がありました。

C++11以降では、

auto it = numbers.begin();

と簡潔に書けます。

nullptrが追加された

C++11では、ヌルポインタを表すためのnullptrが追加されました。

int* p = nullptr;

従来使われていた、

int* p = NULL;

などよりも型の扱いが明確になります。

ラムダ式が追加された

C++11からラムダ式を利用できます。

auto add = [](int a, int b) {
    return a + b;
};

ラムダ式は、STLのアルゴリズムやコールバック処理などで頻繁に使用されます。

range-based forが追加された

配列やコンテナを簡潔にループできるrange-based forもC++11から利用できます。

for (int x : numbers) {
    std::cout << x << '\n';
}

従来のイテレータを使った記述よりも読みやすくなります。

スマートポインタが本格的に導入された

C++11では、

std::unique_ptr
std::shared_ptr
std::weak_ptr

などのスマートポインタが標準ライブラリに導入されました。

メモリ管理を安全に行いやすくなったことも、C++11の重要な変化です。

このほかにも、ムーブセマンティクスや右辺値参照など、現在のC++に欠かせない機能が多数導入されています。


C++14とは?

C++14は、C++11をさらに使いやすくするための改善が中心となった規格です。

C++11ほど大規模な変更ではありませんが、便利な機能が追加されています。

一般化ラムダが使える

C++14では、ラムダ式の引数にautoを指定できます。

auto add = [](auto a, auto b) {
    return a + b;
};

これにより、異なる型でも利用しやすい汎用的なラムダ式を書けます。

std::make_uniqueが追加された

C++14ではstd::make_uniqueが標準ライブラリに追加されました。

auto p = std::make_unique<int>(10);

std::unique_ptrを安全かつ簡潔に生成できます。


C++17とは?

C++17は、実用性の高い機能が多数追加された規格です。

現在でも多くの開発環境やプロジェクトで利用されています。

if constexprが追加された

C++17ではif constexprが導入されました。

if constexpr (condition) {
    // 条件が成立する場合にコンパイルされる処理
}

特にテンプレートプログラミングで便利な機能です。

構造化束縛が使える

複数の値を分解して変数に代入する構造化束縛もC++17から利用できます。

std::pair<int, std::string> p{1, "Apple"};

auto [id, name] = p;

コードを簡潔に書きやすくなります。

std::optionalが追加された

std::optionalを使うと、「値が存在する場合」と「値が存在しない場合」を明示的に表現できます。

std::optional<int> value;

エラー処理や検索結果などを扱う際に便利です。

std::filesystemが標準化された

C++17では、ファイルやディレクトリを操作するstd::filesystemも標準化されました。

#include <filesystem>

このほかにも、

std::any
std::string_view

など、現在でもよく利用される機能が追加されています。


C++20とは?

C++20は、C++11以来の大規模なアップデートのひとつです。

代表的な機能として、

Concepts
Ranges
Coroutines
Modules

などがあります。

Conceptsが追加された

Conceptsを利用すると、テンプレートに渡せる型の条件を分かりやすく記述できます。

#include <concepts>

template<typename T>
concept Number = std::integral<T>;

template<Number T>
T add(T a, T b) {
    return a + b;
}

従来の複雑なテンプレートエラーを減らし、コードの意図を明確にできます。

Rangesが追加された

Rangesは、コンテナや範囲を扱う処理をより柔軟に記述するための仕組みです。

#include <ranges>

STLアルゴリズムと組み合わせることで、データ処理をより宣言的に書けます。

コルーチン機構が導入された

C++20では、

co_await
co_yield
co_return

といったコルーチンを構成するための言語機能が導入されました。

非同期処理やジェネレーターなどを実装するための基盤として利用できます。

ただし、C++20でコルーチンの言語機構が導入されたことと、高水準なコルーチン用ライブラリがすべて揃ったことは同じではありません。

Modulesが導入された

C++20ではModulesも言語規格に導入されています。

従来の、

#include "header.hpp"

を中心としたヘッダーファイル方式とは異なる、新しいコード分割・再利用の仕組みです。

ただし、Modulesの対応状況はコンパイラや開発環境によって異なります。

C++20に規格上含まれているからといって、すべての環境で同じように利用できるとは限りません。


C++23とは?

C++23は、C++20に続く正式なC++規格です。

2026年8月時点では、正式に公開されている最新のC++標準となっています。

なお、一般名称はC++23ですが、正式なISO規格文書は、

ISO/IEC 14882:2024

として2024年に発行されています。

そのため、「C++23」という名称とISO規格文書の発行年が異なる点には注意が必要です。

C++23で追加・改善された機能

C++23では言語機能と標準ライブラリの両方に多数の改善があります。

代表的な標準ライブラリ機能には、

std::expected
std::print
std::println
std::stacktrace

などがあります。

対応環境では、

#include <print>

int main() {
    std::println("Hello, C++23!");
}

のような記述が可能です。

ただし、C++23モードでコンパイルしているからといって、C++23のすべての標準ライブラリ機能が利用できるとは限りません。

コンパイラだけでなく、使用している標準ライブラリの実装状況にも影響されます。

C++26とは?

C++23の次に予定されている規格がC++26です。

2026年8月時点では、C++26はまだ正式に公開されたISO標準ではありません。

次期C++規格として策定が進められており、Draft International Standardの段階まで進んでいます。

C++26の機能を先行して試せる場合がある

GCCやClangなどの新しいコンパイラでは、C++26に向けて策定されている機能の一部を利用できる場合があります。

GCCでは新しいバージョンなら、

g++ -std=c++26 main.cpp

のように指定できます。

バージョンによっては、開発段階の名称である、

g++ -std=c++2c main.cpp

が使われる場合もあります。

ただし、C++26は2026年8月時点では正式規格ではないため、使用できる機能や仕様がコンパイラによって異なる可能性があります。

C++のバージョンごとの違いを一覧で比較

主要なC++規格を整理すると、次のようになります。

規格主な特徴
C++98最初のISO標準C++
C++03C++98の修正・改善
C++11Modern C++の基礎となる大型アップデート
C++14C++11の改善
C++17if constexpr、構造化束縛、std::optionalなど
C++20Concepts、Ranges、Coroutines、Modulesなど
C++23C++20からさらに多数の機能を追加・改善
C++262026年8月時点では策定中の次期規格

学習上は、

C++98 / C++03
↓
旧来のC++

C++11
↓
Modern C++への大きな転換点

C++17
↓
現在でも幅広く使われる実用的な規格

C++20
↓
より現代的な大型アップデート

C++23
↓
現在の最新正式規格

C++26
↓
次期規格

と整理すると理解しやすいでしょう。


C++のバージョンを確認する方法

「C++のバージョンを確認したい」といっても、確認対象には大きく分けて2種類あります。

1. コンパイラのバージョン
2. コンパイル時に使用しているC++規格

この2つを区別することが重要です。


GCC・g++のバージョンを確認する方法

GCC系のC++コンパイラを利用している場合は、ターミナルやコマンドプロンプトで次のコマンドを実行します。

g++ --version

たとえば、

g++ (GCC) 15.x.x

のような結果が表示されます。

ここで表示される数字はC++規格ではありません。

たとえば「GCC 15」と表示されても、「C++15を使用している」という意味ではありません。

あくまでGCCというコンパイラ自体のバージョンを示しています。


Clangのバージョンを確認する方法

Clangを使用している場合は、

clang++ --version

を実行します。

たとえば、

clang version 20.x.x

などと表示されます。

この場合も「C++20」という意味ではありません。

Clangというコンパイラのバージョンです。


MSVCのバージョンを確認する方法

Visual Studioなどで利用されるMicrosoft C++コンパイラでは、Developer Command Promptなどから、

cl

を実行するとバージョン情報を確認できます。

表示される、

Microsoft (R) C/C++ Optimizing Compiler ...

などの情報から、使用しているMSVCコンパイラを確認できます。


コンパイル時にC++規格を指定する方法

GCCでは、-std=オプションを利用してC++規格を指定できます。

C++17を指定する

g++ -std=c++17 main.cpp

C++20を指定する

g++ -std=c++20 main.cpp

C++23を指定する

g++ -std=c++23 main.cpp

Clangでも基本的な指定方法は同様です。

clang++ -std=c++20 main.cpp

コンパイラのバージョンによって対応しているC++規格や機能が異なるため、古いコンパイラでは新しい規格を指定できないことがあります。


プログラムからC++規格を確認する方法

現在どのC++規格としてコンパイルされているかを確認する方法として、__cplusplusという定義済みマクロがあります。

次のコードを実行します。

#include <iostream>

int main() {
    std::cout << __cplusplus << '\n';
}

__cplusplusの代表的な値

代表的な値は次のとおりです。

C++規格__cplusplus
C++98 / C++03199711L
C++11201103L
C++14201402L
C++17201703L
C++20202002L
C++23202302L

たとえば、

g++ -std=c++17 main.cpp

でコンパイルし、

201703

と表示された場合は、C++17モードでコンパイルされていると判断できます。

__cplusplusはコンパイラのバージョンではない

__cplusplusが示しているのは、

「どのC++言語規格のモードとしてコンパイルされているか」

です。

GCCやClangなど、コンパイラそのもののバージョンを示しているわけではありません。


__cplusplusを使ってC++規格ごとに処理を変える方法

__cplusplusは確認だけでなく、条件付きコンパイルにも利用できます。

#if __cplusplus >= 202002L

// C++20以上

#elif __cplusplus >= 201703L

// C++17以上

#else

// C++17未満

#endif

複数のC++規格をサポートするライブラリなどでは、このような方法が利用されます。


Visual Studioで__cplusplusを確認するときの注意点

MSVCでは、__cplusplusの扱いに注意が必要です。

互換性維持のため、設定によっては新しいC++規格を利用していても、

199711L

が返されることがあります。

正しい規格に対応した値を取得したい場合は、

/Zc:__cplusplus

オプションを有効にします。

たとえば、

cl /std:c++20 /Zc:__cplusplus main.cpp

のように指定します。

MSVCでは_MSVC_LANGも確認できる

MSVCには、

_MSVC_LANG

というマクロもあります。

_MSVC_LANGは、MSVCで選択されているC++言語標準を確認するときに利用できます。

そのため、Visual StudioやMSVC環境では、

__cplusplus

だけで判断せず、必要に応じて_MSVC_LANGも確認するとよいでしょう。


C++規格とコンパイラ対応状況の違いに注意

C++では、規格に機能が追加されたことと、その機能を自分の開発環境ですぐ利用できることは必ずしも同じではありません。

たとえばC++23には新しい機能が規定されていても、

GCC
Clang
MSVC
標準ライブラリ
IDE
ビルド環境

などのバージョンによって、実際の対応状況は異なります。

そのため、実務で新しいC++規格を採用するときは、

C++規格
+
コンパイラ
+
標準ライブラリ
+
OS
+
ビルド環境

をセットで確認することが重要です。


C++17とC++20では使えるコードが異なる

使用するC++規格によって、同じソースコードでもコンパイルできるかどうかが変わります。

たとえば、C++20のConceptsを使用した次のコードがあります。

#include <concepts>

template<std::integral T>
T add(T a, T b) {
    return a + b;
}

これを、

g++ -std=c++17 main.cpp

としてコンパイルすると、C++17にはConceptsがないため基本的にコンパイルできません。

一方、

g++ -std=c++20 main.cpp

なら、Conceptsに対応しているコンパイラでコンパイルできます。

このように、C++プログラムで利用できる機能は、

ソースコード
+
使用するC++規格
+
コンパイラ
+
標準ライブラリ

の組み合わせによって決まります。


どのC++バージョンを使えばよい?

これからC++を学習する場合、C++98やC++03から始める必要性は高くありません。

現在のC++を学ぶなら、

C++17
C++20
C++23

を中心に理解するとよいでしょう。

初心者ならC++17から学ぶのもおすすめ

C++17では、

auto
nullptr
スマートポインタ
ラムダ式
range-based for
構造化束縛
std::optional
std::filesystem

など、現在のC++開発で重要な機能を幅広く学べます。

そのため、C++の基本文法やSTLを理解しながらModern C++を身につける土台として適しています。

C++20も積極的に学ぶ

C++17の基本を理解した後は、

Concepts
Ranges
Coroutines
Modules

など、C++20以降の機能を学ぶと、より現代的なC++コードを理解できるようになります。

新規開発では対応環境も確認する

最新規格だから必ず採用すべきというわけではありません。

実務では、

使用するコンパイラ
CI環境
OS
外部ライブラリ
チームの開発環境
サポート対象

などを考慮してC++規格を決めます。

C++23を採用したくても、使用しているコンパイラやライブラリが必要な機能に対応していなければ、C++20やC++17を選択することもあります。


C++のバージョンについて覚えておきたいポイント

C++のバージョンについて理解するときは、まず、

「C++規格」と「コンパイラのバージョン」は別物

と覚えておくことが重要です。

C++規格は、

C++98
↓
C++03
↓
C++11
↓
C++14
↓
C++17
↓
C++20
↓
C++23
↓
C++26

という流れで発展しています。

特にC++11はModern C++への大きな転換点となった規格です。

その後、C++17で実用的な機能が増え、C++20ではConceptsやRangesなどの大規模な機能追加が行われました。

2026年8月時点ではC++23が最新の正式規格であり、C++26は次期規格として策定が進められています。

自分の環境を確認するときは、まず、

g++ --version

または、

clang++ --version

などでコンパイラのバージョンを確認します。

さらに、

std::cout << __cplusplus << '\n';

を利用すれば、現在どのC++規格としてコンパイルされているかを確認できます。

この2つを区別して確認できるようになると、「なぜこのコードがコンパイルできないのか」「自分の環境はC++20に対応しているのか」といった問題も切り分けやすくなります。

以上、C++のバージョンの違いについてでした。

最後までお読みいただき、ありがとうございました。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次