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

[[Microsoft Visual C++>http://msdn.microsoft.com/ja-jp/vstudio/hh386302]] (以下VC++)のC++規格対応状況についてまとめています。

#contents

*概要 [#about]

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

*コンパイラバージョン一覧 [#vc-ver]

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

|~VC++バージョン|~略称|~@code{_MSC_VER}; の値|~備考|h
|LEFT:|LEFT:|RIGHT:|LEFT:|c
|~Visual C++ 2008|2008|1500||
|~Visual C++ 2010|2010|1600||
|~Visual C++ 2012|2012|1700||
|~[[Visual C++ Compiler November 2012 CTP>http://www.microsoft.com/en-us/download/details.aspx?id=35515]]|2012 CTP|1700|コンパイラのみの更新。IntelliSense等は非対応。|
|~Visual C++ 2013|2013|1800||
|~[[Visual C++ Compiler November 2013 CTP>http://www.microsoft.com/en-us/download/details.aspx?id=41151]]|2013 CTP|1800|コンパイラのみの更新。IntelliSense等は非対応。|

*規格対応表 [#table]

**C++11 [#table-cpp11]

|~規格|>|>|>|>|>|~対応表|~説明等|h
|~|~2008|~2010|~2012|~2012&br;CTP|~2013|~2013&br;CTP|~|h
|LEFT:|CENTER:BGCOLOR(#ffffe0):|CENTER:BGCOLOR(#e0eeff):|CENTER:BGCOLOR(#eeffe0):|CENTER:BGCOLOR(#eeffe0):|CENTER:BGCOLOR(#ffe0ff):|CENTER:BGCOLOR(#ffe0ff):|LEFT:|c
|~extern template|●|●|●|●|●|●|@code{extern template class std::vector<MyClass>;};|
|~long long int 型|●|●|●|●|●|●|@code{long long n = 0LL; unsigned long long u = 1ULL;};|
|~C99対応:可変引数マクロ|●|●|●|●|●|●|@code{#define DEBUG_PRINTF(f,...) std::printf(f, __VA_ARGS__)};|
|~連続した右山括弧の解釈|●|●|●|●|●|●|テンプレートの右山括弧が連続しても右シフト演算子として解釈しない。|
|~override|▲&note{override:デストラクタには指定できない。};|▲&note{override};|●|●|●|●|メンバ関数オーバライドの明示。|
|~auto||●|●|●|●|●|型推論: @code{auto itr = vec.begin();};|
|~nullptr||●|●|●|●|●|nullポインタリテラル。 @code{0}; や @code{NULL}; の代わりに使う。|
|~static_assert||●|●|●|●|●|コンパイル時アサート。 @code{static_assert(sizeof(int) == 4, "error!!");};|
|~新しい関数宣言構文||●|●|●|●|●|戻り値の型を後置する。 @code{auto func() -> int;};|
|~拡張friend宣言||●|●|●|●|●|@code(template<typename T> class MyClass { friend T; };);|
|~ローカル型、無名型のテンプレート引数使用||●|●|●|●|●|@code{{struct { int n; } x; std::vector<decltype(x)> v;}};|
|~ラムダ式||▲&note{lambda:関数ポインタへの暗黙の変換等には非対応。};|●|●|●|●|関数オブジェクトを返す式。 @code{{[](int n){ return n * 2; };}};|
|~decltype||▲&note{bug:バグが多い模様。};|▲&note{bug};|●|●|●|式や関数の型を返す。 @code{decltype(x + y) n = x + y;};|
|~enum class|||●|●|●|●|強い型付けを持つ列挙型。 @code{{enum class E { A, B }; E e = E::A;}};|
|~列挙型の基盤型指定|||●|●|●|●|@code{enum E : char { E_A, E_B };}; のように基盤型を指定できる。|
|~列挙型の前方宣言|||●|●|●|●|@code{enum E : int;}; のように列挙型を前方宣言できる。|
|~範囲for文|||●|●|●|●|Range-based for: @code{{for (auto n : nums) { func(n); }}};|
|~final|||●|●|●|●|メンバ関数オーバライドの禁止。|
|~rvalue参照とムーブセマンティクス|||▲&note{move:ムーブコンストラクタとムーブ代入演算子の暗黙の定義には非対応。};|▲&note{move};|▲&note{move};|●|@code{T&&};, @code{std::move};, @code{std::forward};, etc...|
|~明示的型変換演算子||||●|●|●|@code{explicit operator T() const;};|
|~生文字リテラル||||●|●|●|@code{R"(}; と @code{")}; とで括った中に特殊文字や改行等をそのまま書ける。|
|~関数テンプレートのデフォルトテンプレート引数||||●|●|●|@code{template<typename T = int> T func();};|
|~委譲コンストラクタ||||●|●|●|コンストラクタの初期化子で同クラスの他のコンストラクタを呼び出せる。|
|~可変引数テンプレート||||●|●|●|Variadic Templates: @code{template<typename ... Types>};|
|~統一的な初期化構文||||●|●|●|Uniform initialization: @code(int n{ 0 }; std::vector<int> v{ 1, 2 };);|
|~初期化子リスト||||▲&note{lib-support:標準ライブラリは非対応。};|●|●|@code(std::initializer_list<T>); による初期化子リストの受け取り。|
|~default/delete指定|||||●|●|コンストラクタ等の自動生成を明示したり禁止したりできる。|
|~Template aliases|||||●|●|@code{template<typename T> using array10<T> = std::array<T, 10>;};|
|~メンバ変数の定義時初期化|||||●|●|@code(struct MyStruct { int n = 3; std::string s = "ABC"; };);|
|~alignas||||||●|変数のアラインメントの指定ができる。|
|~alignof||||||●|型のアラインメントを取得できる。|
|~noexcept修飾||||||●|関数の例外送出有無を明示する。 @code{void func() noexcept;};|
|~メンバ関数のlvalue/rvalue参照修飾||||||●|メンバ関数を @code{&}; や @code{&&}; で修飾して呼び出し制御できる。|
|~継承コンストラクタ||||||●|基本クラスのコンストラクタを継承。 @code(struct U : T { using T::T; };);|
|~拡張sizeof||||||●|インスタンス生成せずメンバ変数に対して @code{sizeof(T::value)}; と書ける。|
|~C99対応:__func__||||||●|プリプロセスで関数名に変換されるマクロ。|
|~constexpr||||||▲&note{:コンストラクタやメンバ関数の修飾は不可。標準ライブラリは非対応。};|@code{constexpr}; による関数戻り値の定数化等。|
|~char16_t, char32_t|||||||UTF-16、UTF-32文字型。|
|~Unicode文字列リテラル|||||||@code{u"UTF-16"; U"UTF-32"; u8"UTF-8";};|
|~inline namespace|||||||1つ外側の名前空間に透過される名前空間。|
|~noexcept演算子|||||||式が例外を投げる可能性があるか否かを返す。|
|~thread_local|||||||スレッドローカル記憶域。 @code{thread_local int n = 100;};|
|~ユーザ定義リテラル|||||||リテラルのサフィックスを定義できる。|
|~無制限の共用体|||||||共用体メンバにクラス型を持てる。 @code{{union U { int n; std::string s; };}};|
|~属性構文|||||||@code{&#x5b;&#x5b;attr&#x5d;&#x5d;}; 構文による属性指定。|

**C++14 [#table-cpp14]

|~規格|>|>|>|>|>|~対応表|~説明等|h
|~|~2008|~2010|~2012|~2012&br;CTP|~2013|~2013&br;CTP|~|h
|LEFT:|CENTER:BGCOLOR(#ffffe0):|CENTER:BGCOLOR(#e0eeff):|CENTER:BGCOLOR(#eeffe0):|CENTER:BGCOLOR(#eeffe0):|CENTER:BGCOLOR(#ffe0ff):|CENTER:BGCOLOR(#ffe0ff):|LEFT:|c
|~decltype(auto)||||||●|戻り値をそのままの型で受け取る。 @code{decltype(auto) r = getRefInt();};|
|~通常関数の戻り値型推論||||||●|関数の戻り値型を推論。 @code{{auto func() { return 1; } // 戻り値型は int}};|
|~ジェネリックラムダ式||||||●|@code{{[](auto x, decltype(x) y){ return x + y; };}};|
|~汎用ラムダキャプチャ|||||||@code{{[x = x + 1, &y = y]{ return x + y; };}};|
|~2進数リテラル|||||||@code{{int n = 0b11001100;}};|
|~動的配列|||||||@code{{void func(std::size_t n) { int nums[n]; /* ... */ }}};|
|~変数テンプレート|||||||@code{{template<typename T> constexpr T zero = static_cast<T>(0);}};|
|~constexpr関数の制限緩和|||||||constexpr関数でローカル変数の宣言等々を許可する。|

*参考サイト [#link]

-[[Announcing the Visual C++ Compiler November 2013 CTP - Visual C++ Team Blog>http://blogs.msdn.com/b/vcblog/archive/2013/11/18/announcing-the-visual-c-compiler-november-2013-ctp.aspx]]
-[[コンパイラの実装状況 - cpprefjp>https://sites.google.com/site/cpprefjp/implementation-status]]
-[[C++0xの言語拡張まとめ - Faith and Brave>http://faithandbrave.hateblo.jp/entry/20071022/1193052163]]
-[[C++11 FAQ - Bjarne Stroustrup's Homepage>http://www.stroustrup.com/C++11FAQ.html]]
-[[「Visual C++ Compiler November 2012 CTP」で追加された6つの新機能 - CodeZine>http://codezine.jp/article/detail/7061]]
-[[C++14にやってくる見た目に分かりやすい新機能 - 本の虫>http://cpplover.blogspot.jp/2013/05/c14.html]]