C++17 の最終機能

先週のオウルでの C++ 委員会会議で、C++17 は機能が完成し、国際標準になりつつあります。ジャクソンビルでの最後の会議の後、私は大きな驚きを期待することはほとんどできませんでしたが、オウルはいくつかの重要で興味深い機能を新しい標準に追加することができました. Reddit には非常に優れた概要があり、Herb Sutter による最近の CppCast (および彼の旅行レポート) も優れた洞察を提供します。また、C++17 のより完全な概要は、Michael Wong によるプレゼンテーションとして入手できます。

まず第一に

私が言ったように、ジャクソンビルでの会議の後、多くのことがすでに非常に明確になっていました。私は、C++17 に移行する、または移行しない提案について、3 部構成のブログ シリーズを書きました。私たちは C++ の新しい時代に入りつつあります。この時代では、多くの場合、次の標準の一部となる強力な技術仕様と共に標準がリリースされます。つまり、C++17 以外の機能 (コンセプトやモジュールなど) は、今後のコンパイラ リリースでアドオンとして利用できるようになります。 Visual Studio は現在モジュールを提供していますが、GCC は概念をサポートする最初のコンパイラです。 Clang はモジュールもサポートしており、Visual Studio と Clang の両方がモジュール TS の仕様に基づく実装をすぐに持つ可能性があります。

また、次の 2 回の会議では主にレビュー、フィードバック、および国家機関 (別名 ISO メンバーの代表団) によって報告された問題が処理されることを覚えておいてください。これにより、標準に新しいものが追加されることはありませんが、マイナーまたはメジャーな変更が含まれる可能性があります。しかし、すべての機能が最終レビューを通過することを願っています.

C++17 の最終ハイライト

std::variant

私にとって最も驚くべきものから始めましょう。はい、真剣に、C++17 は std::variant をもたらします。これはクールであり、バリアントやその他の関連するアイデアに基づいて構築される将来の機能への道を開きます。パターン マッチングなどについては、C++Now で David Sankel から非常に良い話がありました。 std::variant は、boost::variant およびその他のバリアント ライブラリの経験に基づいて設計されています。 boost::variant:

に非常によく似た API があります。
variant<int, float> v, w;
v = 12;
int i = get<int>(v);
w = get<int>(v);
w = get<0>(v); // same effect as the previous line
w = v; // same effect as the previous line

get<double>(v); // ill formed
get<3>(v); // ill formed

try {
  get<float>(w); // will throw.
}
catch (bad_variant_access&) {}

この機能が TS の回り道ではなく、C++17 標準に移行されるのは素晴らしいことです。

if constexpr(式)

これは static if (多かれ少なかれ) の C++ バージョンです。それは私にとってジャクソンビルのハイライトの 1 つでしたが、当時は成功しませんでした。予想通り、C++17 の Oulu での最終レビューに合格しました。これにより、コンパイル時に constexpr が true と評価された場合、C++ は特定のブロックのみを簡単にコンパイルできるようになりました:

if constexpr (std::is_integer ...) { //integerstuff }
else if constexpr (std::is_floating_point ...) { //floatingpointstuff }
else { // NaN ;) }

この提案では、コンパイル時に constexpr を含めるには true でなければならないと明示的に述べていますが、これは static_assert には影響しません。選択されていないブロックの static_assert は、引き続きトリガーされます。これは、標準では不適切と見なされます。

また興味深い:この機能は if constexpr と書かれていますが、標準的な言い回しではまだ constexpr if と呼ばれていますが、if constexpr のように定義されています。

テンプレートの自動

C++14 では、ラムダは auto でジェネリック パラメーターを持つことができるようになりました。これは、(型ではない) テンプレート パラメーターでも使用できるようになりました。 auto は class や typename よりも短いため、テンプレート コードの記述が容易になります。これは可変個引数テンプレートでも許可されます。 template.

構造化バインディング

これまで、 std::tie を悪用して、結果の型を手動で処理する代わりに、タプルまたはペアを異なる変数に直接割り当てる既知のトリックがありました。これはハックであり、変数も存在する必要がありましたが、変数を宣言して 1 行で初期化できるようになりました:

auto [a , b , c] = getvalues();

中括弧が必要です。getvalues はタプルを返します。 std::pair は提案で言及されていないため、一部の挿入メソッドで STL によって返されるペアでこれが機能するかどうかは不明です。

if とイニシャライザで切り替える

if ステートメントで変数を宣言できるようになりました:if(int x =42; true !=false)、これは以前の提案と組み合わせることができます。 if ステートメントでは、宣言された変数は if ステートメントの else 部分でも有効です。私は、Modern C++ Design が中括弧を使用してこれを達成する方法をすでに示していたことを覚えていますが、それは単一の変数に対してのみでした.

これには、if または switch でのみロックするなどの興味深いユース ケースがあり、ステータス コードを返すすべての関数を if のスコープ内で処理できるようになりました。基本的に、これは { var x =value; と書くのと同じです。 if(...){}else{}}.

さらに

これがすべてではありません。たとえば、コピー省略の改善があります。名前空間 std[0-9]+ は、将来の標準のために予約されています。 reddit の概要には、多くの興味深い議論やコメントも含まれています。

C++17 は標準をさらに進化させ、標準化のためのツールは成熟し、機能しています。おそらく C++ にとって最大のメリットです。次の C++ 標準 (別名 C++NEXT/C++20) に特定の機能を追加したい人は、今から計画を立て始める必要があります。標準化はボランティア活動によって推進されており、有給の委員会はなく、ほとんどの委員会メンバーは C++ 関連の日常業務を行っています。 isocpp.org には優れた詳細な概要ページがあり、参加できるさまざまなメーリング リストやワーキング グループがあります。