プログラミング/C++/VC++のC++規格対応状況 のバックアップ(No.2)


Microsoft Visual C++ (以下VC++)のC++規格対応状況についてまとめています。

概要

VC++は、2013年12月時点の最新コンパイラである Visual C++ Compiler November 2013 CTP においてもまだC++11以降の規格を完全にサポートできていません。
とはいえ、IDE自体は使いやすいですし、そもそも仕事等でVC++を使わざるを得ない状況はどうしてもあります。
そういった場合に、今使っているVC++のバージョンでどこまでC++11以降の規格を使ってコードを書けるのか簡単にわかるようにこのページを作成しました。

コンパイラバージョン一覧

略称は後述の規格対応表で用います。

VC++バージョン略称_MSC_VER の値備考
Visual C++ 200820081500
Visual C++ 201020101600
Visual C++ 201220121700
Visual C++ Compiler November 2012 CTP2012 CTP1700コンパイラのみの更新。IntelliSense等は非対応。
Visual C++ 201320131800
Visual C++ Compiler November 2013 CTP2013 CTP1800コンパイラのみの更新。IntelliSense等は非対応。

規格対応表

C++11

規格対応表説明等
2008201020122012
CTP
20132013
CTP
extern templateextern template class std::vector<MyClass>;
long long int 型long long n = 0LL; unsigned long long u = 1ULL;
C99対応:可変引数マクロ#define DEBUG_PRINTF(f,...) std::printf(f, __VA_ARGS__)
連続した右山括弧の解釈テンプレートの右山括弧が連続しても右シフト演算子として解釈しない。
override*1*2メンバ関数オーバライドの明示。
auto型推論: auto itr = vec.begin();
nullptrnullポインタリテラル。 0NULL の代わりに使う。
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;
ラムダ式*3関数オブジェクトを返す式。 [](int n){ return n * 2; };
decltype*4*5式や関数の型を返す。 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参照とムーブセマンティクス*6*7*8T&&, 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 };
初期化子リスト*9std::initializer_list<T> による初期化子リストの受け取り。
default/delete指定コンストラクタ等の自動生成を明示したり禁止したりできる。
Template aliasestemplate<typename T> using array10<T> = std::array<T, 10>;
メンバ変数の定義時初期化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*10constexpr による関数戻り値の定数化等。
char16_t, char32_tUTF-16、UTF-32文字型。
Unicode文字列リテラルu"UTF-16"; U"UTF-32"; u8"UTF-8";
inline namespace1つ外側の名前空間に透過される名前空間。
noexcept演算子式が例外を投げる可能性があるか否かを返す。
thread_localスレッドローカル記憶域。 thread_local int n = 100;
ユーザ定義リテラルリテラルのサフィックスを定義できる。
無制限の共用体共用体メンバにクラス型を持てる。 union U { int n; std::string s; };
属性構文[[attr]] 構文による属性指定。

C++14

規格対応表説明等
2008201020122012
CTP
20132013
CTP
decltype(auto)戻り値をそのままの型で受け取る。 decltype(auto) r = getRefInt();
通常関数の戻り値型推論関数の戻り値型を推論。 @code{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;
動的配列void func(std::size_t n) { int nums[n]; /* ... */ }
変数テンプレートtemplate<typename T> constexpr T zero = static_cast<T>(0);
constexpr関数の制限緩和constexpr関数でローカル変数の宣言等々を許可する。

参考サイト

*1 *2  デストラクタには指定できない。
*3  関数ポインタへの暗黙の変換等には非対応。
*4 *5  バグが多い模様。
*6 *7 *8  ムーブコンストラクタとムーブ代入演算子の暗黙の定義には非対応。
*9  標準ライブラリは非対応。
*10  コンストラクタやメンバ関数の修飾は不可。標準ライブラリは非対応。