C++14 は、 C++プログラミング言語のISO / IEC 14882 規格のバージョンです。主にバグ修正と小さな改善を特徴とするC++11の小さな拡張として意図されており、 C++17に置き換えられました。その承認は 2014 年 8 月 18 日に発表されました。[ 1 ] C++14 は、2014 年 12 月に ISO/IEC 14882:2014 として公開されました。[ 2 ]
以前のC++標準の改訂は著しく遅れていたため、承認されるまでは「C++1y」という名称が使われることがありました。これは、C++11標準が2010年より前にリリースされると予想されていた際に「C++0x」と呼ばれていたのと同様です(実際には2010年、そして最終的には2011年にずれ込みましたが)。
これらは、C++14のコア言語に追加された機能です。
C++11 では、ラムダ関数はreturn ステートメントに与えられた式の型に基づいて戻り値の型を推論することができました。C++14 では、この機能がすべての関数に提供されます。また、これらの機能をラムダ関数にも拡張し、形式ではない関数の戻り値の型推論も可能にしていますreturn expression;。[ 3 ]
戻り値の型推論を誘発するには、関数をauto戻り値の型として宣言する必要がありますが、C++11 では末尾の戻り値の型指定子は不要です。
auto deduceReturnType (); // 戻り値の型を決定します。関数の実装で複数の戻り値式が使用される場合、それらはすべて同じ型を推論する必要があります。[ 4 ]
戻り値の型を推論する関数は前方宣言できますが、定義されるまでは使用できません。それらの定義は、使用する翻訳単位が利用できる状態である必要があります。
このタイプの関数では再帰を使用できますが、再帰呼び出しは関数の定義内の少なくとも 1 つの return ステートメントの後に発生する必要があります。[ 4 ]
auto correct ( int i ) { if ( i == 1 ) { return i ; // 戻り値の型は int と推論される} return correct ( i - 1 ) + i ; // これで呼び出し可能}auto wrong ( int i ) { if ( i != 1 ) return wrong ( i - 1 ) + i ; // 呼び出しが早すぎる。前の return 文がない。} return i ; // 戻り値の型は int と推論される}C++11 では、2 つの型推論方法が追加されました。autoは、与えられた式に基づいて適切な型の変数を作成する方法でした。 は、decltype与えられた式の型を計算する方法でした。しかし、decltypeと はauto異なる方法で型を推論します。特に、autoは常に を使用するかのように非参照型を推論しますがstd::decay、 はauto&&常に参照型を推論します。ただし、 は、decltype式の値カテゴリと推論する式の性質に基づいて、参照型または非参照型を推論するように促すことができます。[ 5 ] [ 3 ]
int i ; int && f (); auto x3a = i ; // decltype(x3a) は int ですdecltype ( i ) x3d = i ; // decltype(x3d) は int ですauto x4a = ( i ); // decltype(x4a) は int ですdecltype (( i )) x4d = ( i ); // decltype(x4d) は int& ですauto x5a = f (); // decltype(x5a) は int ですdecltype ( f ()) x5d = f (); // decltype(x5d) は int&&C++14では、このdecltype(auto)構文が追加されました。これにより、auto宣言において指定された式に関する規則を使用できるようになりますdecltype。
この構文は、関数の戻り値の型推論にの代わりに 構文を使用することで、戻り値の型推論decltype(auto)にも使用できます。 [ 4 ]decltype(auto)auto
C++11では、constexprで宣言された関数という概念が導入されました。これはコンパイル時に実行できる関数です。その戻り値は、整数テンプレート引数など、定数式を必要とする操作で使用できます。ただし、C++11のconstexpr関数は、返される式を1つだけ(およびstatic_assertsと少数のその他の宣言)しか含めることができませんでした。
C++14 ではこれらの制限が緩和されています。constexpr で宣言された関数には、次のものを含めることができます。[ 3 ]
staticまたはthread_local変数。ifとswitch。for。constconstexpr宣言されていない非静的メンバ関数への呼び出しも含まれます。gotoC++14 の緩和された constexpr で宣言された関数では、ステートメントは禁止されています。
また、C++11 では、宣言されたすべての非静的メンバ関数は、に関してconstexpr暗黙的に宣言されると規定されていました。これはその後削除され、非静的メンバ関数は非静的である可能性があります。[ 6 ]ただし、上記の制限に従い、非静的メンバ関数は、そのオブジェクトのライフタイムが定数式の評価内で開始された場合にのみ、クラスメンバを変更できます。constthisconstconstconstexpr
以前のバージョンのC++では、関数、クラス、または型エイリアスのみがテンプレート化可能でした。C++14 では、テンプレート化された変数の作成が可能になります。提案書に示されている例として、さまざまな型に対して円周率πpiの値を取得できる変数があります(たとえば、整数型として読み込んだ場合、または、またはとして読み込んだ場合、それぞれ、または精度で可能な限り最も近い値など)。3floatdoublelong doublefloatdoublelong double
テンプレートの通常のルールは、特殊化を含め、そのような宣言と定義に適用されます。[ 7 ] [ 8 ]
template < typename T > constexpr T PI = T ( 3.141592653589793238462643383 );// 通常の特殊化ルールが適用されます: template <> constexpr const char * PI < const char *> = "pi" ;C++11では、コンストラクタがメンバ自体を初期化しない場合にクラススコープでメンバに適用される式であるデフォルトメンバ初期化子が追加されました。集約の定義が変更され、メンバ初期化子を持つクラスは明示的に除外されるようになったため、集約初期化子を使用することはできません。
C++14 ではこの制限が緩和され、[ 3 ]このような型に対して集約初期化が可能になりました。中括弧で囲まれた初期化リストにその引数の値が指定されていない場合、メンバ初期化子がそれを処理します。[ 9 ]
C++14 の数値リテラルはバイナリ形式で指定できます。[ 3 ]この構文では、プレフィックス0bまたはを使用します。この構文は、 Java、C#、Swift、Go、Scala、Ruby、Python、OCaml0Bなどの他の言語でも使用されており、少なくとも 2007 年以降、一部の C コンパイラでは非公式の拡張機能として使用されています。[ 10 ]
C++14 では、数値リテラル(整数リテラルと浮動小数点リテラルの両方)の桁区切り文字として、シングルクォート文字を任意に使用できます。 [ 11 ]これにより、人間が瞬時に大きな数値を解析しやすくなります。
auto integer_literal = 1'000'000 ; auto floating_point_literal = 0.000'015'3 ; auto binary_literal = 0b0100'1100'0110 ; auto a_dozen_crores = 12'00'00'000 ;C++11では、ラムダ関数のパラメータは具体的な型で宣言する必要があります。C++14ではこの要件が緩和され、ラムダ関数のパラメータを型指定子で宣言できるようになりましたauto。[ 7 ]
auto lambda = []( auto x , auto y ) -> auto { return x + y ; };型推論に関してはauto、ジェネリックラムダはテンプレート引数推論の規則に従います(類似していますが、すべての点で同一ではありません)。上記のコードはこれと同等です。[ 12 ]
struct { template < typename T , typename U > auto operator ()( T x , U y ) const { return x + y ; } } lambda {};ジェネリックラムダは、基本的にテンプレート化されたファンクタラムダです。
C++11 のラムダ関数は、値コピーまたは参照によって外側のスコープで宣言された変数をキャプチャします。これは、ラムダの値メンバーはムーブ専用型にできないことを意味します。[ 13 ] C++14 では、キャプチャされたメンバーを任意の式で初期化できます。これにより、値ムーブによるキャプチャと、外側のスコープに対応する名前の変数を持たずにラムダの任意のメンバーを宣言することの両方が可能になります。[ 7 ]
これは初期化式を用いることで実現されます。
auto lambda = [ value = 1 ] -> int { return value ; };ラムダ関数はlambda1 を返します。これはvalue初期化時に使用された値です。宣言されたキャプチャは、初期化式から型を推論しますauto。
これは、標準std::move関数を使用して、移動によるキャプチャに使用できます。
std :: unique_ptrを使用します。unique_ptr <int> ptr ( new int ( 10 ) ) ;auto lambda = [ value = std :: move ( ptr )] -> int { return * value ; };deprecatedこの属性を使用すると、エンティティを非推奨としてマークできます。これにより、エンティティの使用は合法になりますが、使用が推奨されないことをユーザーに通知し、コンパイル時に警告メッセージが表示される場合があります。オプションの文字列リテラルを引数として指定することで、非推奨の理由を説明し、代替案を提案できます。[[deprecated]][[deprecated("Reason")]]
[[非推奨]] int f ();[[非推奨( "g() はスレッドセーフではありません。代わりに h() を使用してください" )]] void g ( int & x );void h ( int & x );void test () { int a = f (); // 警告: 'f' は非推奨ですg ( a ); // 警告: 'g' は非推奨です: g() はスレッドセーフではありません。代わりに h() を使用してください}C++14 では、共有のタイムド ミューテックスとそれに付随する共有ロック タイプが追加されました。[ 14 ] [ 15 ]
C ++標準ライブラリは、4つの連想コンテナクラスを定義しています。これらのクラスを使用すると、ユーザーはその型の値に基づいて値を検索できます。マップコンテナでは、キーと値を指定できます。検索はキーによって行われ、値が返されます。ただし、検索は常に特定のキー型によって行われます。マップの場合はキー、セットの場合は値自体がキー型です。
C++14 では、比較演算子が実際のキー型と比較できる限り、任意の型を使用してルックアップを実行できます。[ 16 ]std::stringこれにより、から何らかの値へのマップを、const char*またはオーバーロードが利用可能な他の任意の型と比較できるようになります。また、のユーザーにダミーオブジェクトを作成するように強制することなく (たとえば、名前で人を見つけるために全体を作成するなど) 、単一のメンバーの値でoperator< の複合オブジェクトにインデックスを付ける場合にも役立ちます。std::setfindstruct Person
後方互換性を維持するため、異種ルックアップは、連想コンテナに与えられた比較器がそれを許可する場合にのみ許可されます。標準ライブラリクラスとが拡張されstd::less<>、std::greater<>異種ルックアップが可能になっています。[ 17 ]
C++11 ではユーザー定義リテラル接尾辞の構文が定義されましたが、標準ライブラリではそれらのいずれも使用されていませんでした。C++14 では次の標準リテラルが追加されました: [ 16 ]
std::basic_stringタイプを作成するための「s」。std::chrono::duration対応する時間間隔を作成するための「h」、「min」、「s」、「ms」、「us」、「ns」 。std::complex<float>、虚数を作成するための「if」、「i」、「il」 。std::complex<double>std::complex<long double>auto str = "hello world" s ; // auto は std::string を推論しますauto dur = 60 s ; // auto は std::chrono::seconds を推論しますauto z = 1 i ; // auto は std::complex<double> を推論します2 つの「s」リテラルは衝突しません。文字列リテラルは文字列リテラルのみに作用し、秒を表すリテラルは数値のみに作用するためです。[ 18 ]
C++11 で導入された型std::tupleでは、型付き値の集合をコンパイル時定数整数でインデックス付けできます。C++14 では、インデックスではなく型でタプルからフェッチできるように拡張されています。[ 16 ]タプルにその型の要素が複数ある場合、コンパイル時エラーが発生します。[ 19 ]
using std :: string ; using std :: tuple ;tuple < string , string , int > t ( "foo" , "bar" , 7 ); int i = std :: get < int > ( t ); // i == 7 int j = std :: get < 2 > ( t ); // 前と同じ: j == 7 string s = std :: get < string > ( t ); // 曖昧さのためコンパイル時エラーstd::make_uniquestd::make_sharedオブジェクトにも使用できますstd::unique_ptr。[ 7 ]
std::integral_constantoperator()定数値を返すオーバーロードが追加された。 [ 16 ]
クラステンプレートstd::integer_sequenceと関連するエイリアステンプレートは、パラメータパック内の要素のインデックスなど、コンパイル時の整数シーケンスを表すために追加されました。[ 20 ]
グローバル関数std::begin/には、定数イテレータを返す/関数と、逆イテレータを返す/および/std::end関数が追加されました。std::cbeginstd::cendstd::rbeginstd::rendstd::crbeginstd::crend
関数std::exchangeテンプレートは変数に新しい値を代入し、古い値を返します。[ 21 ]
std::equal、、およびの新しいオーバーロードはstd::mismatch、std::is_permutation2 番目の範囲のイテレータのペアを受け取るため、呼び出し元は 2 つの範囲が同じ長さであることを個別にチェックする必要がありません。[ 22 ]
型std::is_final特性は、クラスがマークされているかどうかを検出しますfinal。
ストリームstd::quotedI/Oマニピュレータは、出力時に区切り文字(デフォルトは二重引用符)を配置し、入力時にそれらを取り除き、埋め込まれた区切り文字をエスケープすることにより、埋め込みスペースを含む文字列の挿入と抽出を可能にします。[ 23 ]
Clang は3.4 で標準名 c++1y で C++14 のサポートを終了し、Clang 6 で C++14 をデフォルトの C++ 標準にしました。[ 24 ] GCC はGCC 5 で C++14 のサポートを終了し、GCC 6 で C++14 をデフォルトの C++ 標準にしました。[ 25 ] Microsoft Visual Studio 2017 は「ほぼすべての」 C++14 機能を実装しています。[ 26 ]