Microsoft Visual C++ (以下VC++)のC++規格対応状況についてまとめています。
VC++は、他の主要なC++コンパイラ(gcc、clang)と比べ、C++規格への対応状況が芳しくありません。
とはいえ、IDE自体は使いやすいですし、そもそも仕事等でVC++を使わざるを得ない状況はどうしてもあります。
そういった場合に、今使っているVC++のバージョンでどこまでC++11以降の規格を使ってコードを書けるのか簡単にわかるようにこのページを作成しました。
略称は後述の規格対応表で用います。
| VC++バージョン | 略称 | _MSC_VER の値 | 備考 |
|---|---|---|---|
| Visual C++ 2008 | 2008 | 1500 | |
| Visual C++ 2010 | 2010 | 1600 | |
| Visual C++ 2012 | 2012 | 1700 | |
| Visual C++ Compiler November 2012 CTP | 2012 CTP | 1700 | コンパイラのみの更新。IntelliSense等は非対応。 |
| Visual C++ 2013 | 2013 | 1800 | |
| Visual C++ Compiler November 2013 CTP | 2013 CTP | 1800 | コンパイラのみの更新。IntelliSense等は非対応。 |
| Visual C++ 2015 | 2015 | 1900 |
現在は言語機能についてのみリストアップしています。
| 規格 | 対応表 | 説明等 | ||||||
|---|---|---|---|---|---|---|---|---|
| 2008 | 2010 | 2012 | 2012 CTP | 2013 | 2013 CTP | 2015 | ||
| extern template | ● | ● | ● | ● | ● | ● | ● | extern template class std::vector<MyClass>; |
| long long int 型 | ● | ● | ● | ● | ● | ● | ● | long long n = 0LL; unsigned long long u = 1ULL; |
| 連続した右山括弧の解釈 | ● | ● | ● | ● | ● | ● | ● | テンプレートの右山括弧が連続しても右シフト演算子として解釈しない。 |
| override | ▲*1 | ▲*2 | ● | ● | ● | ● | ● | メンバ関数オーバライドの明示。 |
| C99対応:可変引数マクロ | ▲*3 | ▲*4 | ▲*5 | ▲*6 | ▲*7 | ▲*8 | ▲*9 | #define DEBUG_PRINTF(f,...) std::printf(f, __VA_ARGS__) |
| auto | ● | ● | ● | ● | ● | ● | 型推論: auto itr = vec.begin(); | |
| nullptr | ● | ● | ● | ● | ● | ● | nullポインタリテラル。 0 や NULL の代わりに使う。 | |
| static_assert | ● | ● | ● | ● | ● | ● | コンパイル時アサート。 static_assert(sizeof(int) == 4, "error"); | |
| 新しい関数宣言構文 | ● | ● | ● | ● | ● | ● | 戻り値の型を後置する。 auto func() -> int; | |
| 拡張friend宣言 | ● | ● | ● | ● | ● | ● | template<typename T> class MyClass { friend T; }; | |
| ローカル型、無名型の テンプレート引数使用 | ● | ● | ● | ● | ● | ● | struct { int n; } x; std::vector<decltype(x)> v; | |
| ラムダ式 | ▲*10 | ● | ● | ● | ● | ● | 関数オブジェクトを返す式。 [](int n){ return n * 2; }; | |
| decltype | ▲*11 | ▲*12 | ● | ● | ● | ● | 式や関数の型を返す。 decltype(x + y) n = x + y; | |
| enum class | ● | ● | ● | ● | ● | 強い型付けを持つ列挙型。 enum class E { A, B }; E e = E::A; | ||
| 列挙型の基盤型指定 | ● | ● | ● | ● | ● | enum E : char { E_A, E_B }; のように基盤型を指定できる。 | ||
| 列挙型の前方宣言 | ● | ● | ● | ● | ● | enum E : int; のように列挙型を前方宣言できる。 | ||
| 範囲for文 | ● | ● | ● | ● | ● | Range-based for: for (auto n : nums) { func(n); } | ||
| final | ● | ● | ● | ● | ● | メンバ関数オーバライドの禁止。 | ||
| rvalue参照とムーブセマンティクス | ▲*13 | ▲*14 | ▲*15 | ● | ● | T&&, std::move, std::forward, etc... | ||
| 明示的型変換演算子 | ● | ● | ● | ● | explicit operator T() const; | |||
| 生文字リテラル | ● | ● | ● | ● | R"( と ") とで括った中に特殊文字や改行等をそのまま書ける。 | |||
| 関数テンプレートの デフォルトテンプレート引数 | ● | ● | ● | ● | template<typename T = int> T func(); | |||
| 委譲コンストラクタ | ● | ● | ● | ● | コンストラクタの初期化子で同クラスの他のコンストラクタを呼び出せる。 | |||
| 可変引数テンプレート | ● | ● | ● | ● | Variadic Templates: template<typename ... Types> | |||
| 統一的な初期化構文 | ● | ● | ● | ● | Uniform initialization: int n{ 0 }; std::vector<int> v{ 1, 2 }; | |||
| 初期化子リスト | ▲*16 | ▲*17 | ▲*18 | ● | std::initializer_list<T> による初期化子リストの受け取り。 | |||
| default/delete指定 | ● | ● | ● | コンストラクタ等の自動生成を明示したり禁止したりできる。 | ||||
| Template aliases | ● | ● | ● | template<typename T> using array10<T> = std::array<T, 10>; | ||||
| メンバ変数の宣言時初期化 | ▲*19 | ▲*20 | ● | struct MyStruct { int n = 3; std::string s = "ABC"; }; | ||||
| alignas | ● | ● | 変数のアラインメントの指定ができる。 | |||||
| alignof | ● | ● | 型のアラインメントを取得できる。 | |||||
| noexcept修飾 | ● | ● | 関数の例外送出有無を明示する。 void func() noexcept; | |||||
| メンバ関数の lvalue/rvalue参照修飾 | ● | ● | メンバ関数を & や && で修飾して呼び出し制御できる。 | |||||
| 継承コンストラクタ | ● | ● | 基本クラスのコンストラクタを継承。 struct U : T { using T::T; }; | |||||
| 拡張sizeof | ● | ● | インスタンス生成せずメンバ変数に対して sizeof(T::value) と書ける。 | |||||
| C99対応:__func__ | ● | ● | プリプロセスで関数名に変換されるマクロ。 | |||||
| constexpr | ▲*21 | ▲*22 | constexpr による関数戻り値の定数化等。 | |||||
| char16_t, char32_t | ● | UTF-16、UTF-32文字型。 | ||||||
| Unicode文字列リテラル | ● | u"UTF-16"; U"UTF-32"; u8"UTF-8"; | ||||||
| inline namespace | ● | 1つ外側の名前空間に透過される名前空間。 | ||||||
| noexcept演算子 | ● | 式が例外を投げる可能性があるか否かを返す。 | ||||||
| thread_local | ● | スレッドローカル記憶域。 thread_local int n = 100; | ||||||
| ユーザ定義リテラル | ● | リテラルのサフィックスとその処理を独自に定義できる。 | ||||||
| 無制限の共用体 | ● | 共用体メンバにクラス型を持てる。 | ||||||
| ユニバーサル文字名 | const char* \u3042 = "\U00000041"; // あ = "A" と同義 | |||||||
| 属性構文 | [[attr]] 構文による属性指定。 | |||||||
| 規格 | 対応表 | 説明等 | ||||||
|---|---|---|---|---|---|---|---|---|
| 2008 | 2010 | 2012 | 2012 CTP | 2013 | 2013 CTP | 2015 | ||
| decltype(auto) | ● | ● | 戻り値等をそのままの型で受け取る。 decltype(auto) r = getRefInt(); | |||||
| 通常関数の戻り値型推論 | ● | ● | 関数の戻り値型を推論。 auto func() { return 1; } // 戻り値型は int | |||||
| ジェネリックラムダ式 | ● | ● | [](auto x, decltype(x) y){ return x + y; }; | |||||
| 汎用ラムダキャプチャ | ● | [x = x + 1, &y = y]{ return x + y; }; | ||||||
| 2進数リテラル | ● | int n = 0b11001100; | ||||||
| 数値リテラルの桁区切り | ● | シングルクォートによる桁区切り。 int n = 1'234'567; | ||||||
| サイズ付きのdelete演算子 | ▲*23 | void operator delete(void*, std::size_t) noexcept; | ||||||
| 動的配列 | void func(std::size_t n) { int nums[n]; /* ... */ } | |||||||
| 変数テンプレート | template<typename T> constexpr T zero = static_cast<T>(0); | |||||||
| メンバ変数の宣言時初期化を 含む型の集成体初期化 | struct S { int n = 0; }; S s = { 1 }; | |||||||
| constexpr関数の制約緩和 | constexpr 関数でローカル変数の宣言等々を許可する。 | |||||||
| 初期化子リストの制約緩和 | 集成体の初期化条件を緩和。 | |||||||
| [[deprecated]]属性 | 非推奨機能であることを示す属性指定。 | |||||||