C++14
C++14 とは、C++11のマイナーバージョンアップとラムダ式などの機能追加を行われたバージョン版のC++です。新しい機能を使用するためには、新しいC++コンパイラ(g++, clang++など)が必要です。
読み方
- C++14
- しーぷらすぷらす じゅうよん
目次
概要
C++14では、C++98に対するC++03程度の修正を予定していたが、機能追加を行われることになりました。 2014年度中に仕様が策定される予定です。 C++14の後は、C++17を目指す C++1yが予定されています。
コア言語
- 2進数リテラル
- 実行時サイズの配列
- 通常の関数の戻り値型の推論
- ジェンリックラムダ
- 一般化されたラムダキャプチャ
- constexpr 関数の制限の緩和
- 変数テンプレート
- 軽量コンセプト
2進数リテラル
0b もしくは 0B のプレフィックスをつけて、数値の2進数リテラルを記述できます。
int i = 0b1100; // i = 12
実行時サイズの配列
配列のサイズ(要素数)を実行時の値で指定できるようになります。
void f(std::size_t size) { int a[size]; // 実行時サイズの配列 }
Cとは、sizeofで値がとれないなど、細かい部分で互換性がありません。
クラス内で使用できないケースがあります。 構造体内の動的配列は、 Variable Length Array In Structure(VLAIS) と呼ばれます。 C++14の実行時サイズ配列は、VLAISをサポートしません。
void f(std::size_t size) { struct { int a[size]; // GCC VLAIS, C++14 ではエラーになる } valis; }
通常の関数の戻り値型の推論
ラムダ式と同様に、通常の関数でもreturn文から戻り値の型を推論できるようにします。
auto f(); // 関数宣言では、戻り値の型は、不明 auto f(){return 123;}; // 関数f()の定義で、戻り値の型は int となる。 int x = f();// x = 123;
return文のオペランドの式から推定されます。
K&R Cは、関数の戻り値型を省略した場合、暗黙にint型として扱われました。
f() { return 0.0; } // K&R C, int
K&R Cの短絡的な型省略とC++14の型推論の違いは、C++14の戻り値の型推論機能は、関数本体のreturn文のオペランドの式を評価した結果の型であることです。
decltype(auto)
decltype(auto)は、戻り値型の推定に追加された機能です。
decltype(変数)で、変数の型と同じ型を指定できます。
auto a = 10; // int a = 10; と同義 decltype(a) b; // int b; と同義 std::vector<decltype<a> v; // std::vector<int> v; と同義
ジェンリックラムダ
ラムダ式のパラメータがジェンリックにできるようになります。
[](const auto& a, const auto& b) { return a > b; };
Varadic template parameter(パラメーターパック)も使用できます。
auto f = [](auto ... args) {}; f(); f(0); f(0,1); f(0,1,2,3,4,5);
一般化されたラムダキャプチャ
C++11では、非staticデータメンバーは、コピーキャプチャできませんでした。
int x = 1; // xをコピーしたy, xの参照をキャプチャしたz auto f = [y=x, &z=x] { ... }; auto g = [y = x + 1] { return y; }; // 2を返す
ムーブキャプチャ
std::unique_ptr<int> p(new int(3)); auto f = [p = std::move(p)]{ ...; };
constexpr 関数の制限の緩和
- if, switch による条件分岐を許可
- for, while, do-while のループの許可
- void 戻り値型の許可
- パラメータの参照で書き換えを行う
- 初期化をともなう変数宣言の許可
- static, thread_local は除く
- 変数書き換えの許可
constexpr int abs(int i) { if (i < 0) { i = -i; } return i; }
変数テンプレート
変数定義にテンプレートを使用できるようになります。
template <class T> constexpr T pi = T(3.1415); template <class T> T menseki(T hankei) { return pi<T> * hankei * hankei; }
軽量コンセプト
- コンセプトの軽量版
- テンプレートの型制約機能
数値区切り
「数値区切り」とは、「数値リテラルを単一引用符で区切る」機能です。区切りの桁は、任意です。 大きな数字は、区切りを入れたほうが「人に解りやすい」というメリットがあります。
int a = 1'000; // 千 long int b = 1'000'000; // 100万 long long int c = 1'000'000'000; // 10億
2進数や16進数も区切ると見やすくなります。
uint16_t a = 0b11110000'00001111; uint32_t b = 0xff'00'ff'ff;
小数点を区切ることもできます。
double pi = 3.14159'26535;
非推奨をマークする[[deprecated]]
deprecated属性は、エンティティを非推奨扱いする属性です。 「非推奨扱いの名前」が使用される場合、「警告メッセージ」を出せます。
// 非推奨の関数 [[deprecated]] char * gets(char *str); // コメント [[deprecated("gets is deprecated." " Use gets_s instead.")]]
たとえば、「非推奨の関数」は、いきなり削除はできません。 「現実的な解」として、「非推奨の関数」の実装を置き換えてしまうことが可能かもしれませんが、必ずしも置き換え可能ではありませんし、完全な形の置き換えができるかはわかりません。実装を変更することにより、互換性の問題が発生する可能性など、サイドエフェクトが考えられます。
「非推奨な関数」を利用しているかどうか、気付くのは難しく、C++コンパイラで警告を出し、プログラマに撲滅していって貰うのが良いでしょう。
ライブラリ
- std::make_unique()
- exchange()
- コンパイル時 整数シーケンス
- tupleの型指定 get()
- quoted マニピュレータ
- ユーザー定義リテラルライブラリ
- Type Traits のエイリアステンプレート
- optional 型
- 実行サイズの配列
- 共有 mutex
- ファイルシステム
- ネットワークライブラリ
GNU GCC/g++ C++14 サポート状況
- http://gcc.gnu.org/projects/cxx1y.html
- g++49(GCC 4.9)が比較的いろいろサポートしています。
- Tweak to certain C++ contextual conversions N3323 4.9
- Binary literals N3472 4.3 (GNU) , 4.9 (N3472)
- Return type deduction for normal functions N3638 4.8 (N3386) , 4.9 (N3638)
- (Moved from the standard to a separate technical specification) N3639 ?.? (GNU VLAs) , 4.9 (N3639)
- Generalized lambda capture (init-capture) N3648 4.5 (partial) , 4.9 (N3648)
- Generic (polymorphic) lambda expressions N3649 4.9
- ((deprecated)) attribute N3760 4.9 (N3797)
- Single-quotation-mark as a digit separator N3781 4.9 (N3797)
- g++49 でサポートされていないもの。
- Runtime-sized arrays with automatic storage duration
- Variable templates N3651 No [WIP]
- Relaxing requirements on constexpr functions N3652 No
- Member initializers and aggregates N3653 No
- Clarifying memory allocation N3664 N/A
- Sized deallocation N3778 No
Clang clang++ C++14 サポート状況
- http://clang.llvm.org/cxx_status.html
- clang 3.4(clang++34)
- clang 3.4 で C++14の機能を実装しました。
- C++14は、clang++のオプション -std+c++1y で有効になります。
インストール
Ubuntu
sudo wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add - sudo apt-get install clang-3.4 lldb-3.4
sudo add-apt-repository 'deb http://llvm.org/apt/precise/ llvm-toolchain-precise main' wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key|sudo apt-key add - sudo apt-get update sudo apt-get install clang-3.4 clang-3.4-doc libclang-common-3.4-dev \ libclang-3.4-dev libclang1-3.4 libclang1-3.4-dbg libllvm-3.4-ocaml-dev \ libllvm3.4 libllvm3.4-dbg lldb-3.4 llvm-3.4 llvm-3.4-dev llvm-3.4-doc \ llvm-3.4-examples llvm-3.4-runtime cpp11-migrate-3.4 clang-format-3.4
FreeBSD
sudo pkg install gcc49
sudo pkg install clang34
関連項目
ツイート