すべての開発者が知っておくべきいくつかの素晴らしい最新のC ++機能

言語として、C ++は大きく進化しました。

もちろん、これは一夜にして起こりませんでした。C ++にダイナミズムが欠けていた時期がありました。その言語が好きになるのは難しかった。

しかし、C ++標準委員会がハンドルを回すことを決定したとき、状況は変わりました。

2011年以降、C ++は、多くの人々が望んでいたダイナミックで進化し続ける言語として登場しました。

言語が簡単になったという誤解をしないでください。それは、最も難しいものではないにしても、広く使用されている最も難しいプログラミング言語の1つです。しかし、C ++は、以前のバージョンよりもはるかにユーザーフレンドリーになっています。

前回の投稿では、ここ数年で強化されたC ++アルゴリズムライブラリについて話しました。

今日は、すべての開発者が知りたいいくつかの新機能(ちなみに、すでに8年前のC ++ 11から開始)について見ていきます。

また、この記事ではいくつかの高度な機能をスキップしましたが、将来的にはそれらについて書きたいと思っています。?️

行く!

自動キーワード

C ++ 11が最初に導入されたときauto、生活は楽になりました。

のアイデアはauto、C ++コンパイラにコンパイル中にデータの型を推測させることでした。つまり、型を毎回宣言させるのではありませんnt、int >>>のようなデータ型がある場合、これはとても便利でしたか?map

Original text


行番号5を見てください。。なしで何かを宣言することはできませんinitializer。それは実際には理にかなっています。5行目では、データ型が何であるかをコンパイラに通知していません。

当初、autoやや制限されていました。その後、言語の新しいバージョンでは、より多くのパワーが追加されました!

7行目と8行目では、括弧で囲まれた初期化を使用しました。これもC ++ 11で追加された新機能でした。

を使用する場合はauto、コンパイラが型を推測する方法が必要であることを忘れないでください。

さて、とてもいい質問です。書くとauto a = {1, 2, 3}どうなりますか?それはコンパイルエラーですか?それはベクトルですか?

実際、C ++ 11はpe>を導入しましたdec d autoの場合、ブレースで初期化されたリストはこの軽量コンテナと見なされます。std::initializer_listlare

最後に、前述したように、コンパイラによる型の推定は、複雑なデータ構造がある場合に非常に役立ちます。

25行目をチェックすることを忘れないでください!この式auto [v1,v2] = itr.secondは、文字通りC ++ 17の新機能です。これは構造化バインディングと呼ばれます。以前のバージョンの言語では、各変数を個別に抽出する必要がありました。しかし、構造化されたバインディングにより、はるかに便利になりました。

さらに、参照を使用してデータを取得する場合は、記号を追加するだけです— auto &[v1,v2] = itr.second

きちんとした。

ラムダ式

C ++ 11では、JavaScriptの無名関数のようなラムダ式が導入されました。これらは名前のない関数オブジェクトであり、いくつかの簡潔な構文に基づいてさまざまなスコープの変数をキャプチャします。それらは変数にも割り当てることができます。

ラムダは、コード内で簡単に実行する必要があるが、そのためにまったく別の関数を記述したくない場合に非常に便利です。もう1つのかなり一般的な使用法は、それらを比較関数として使用することです。

上記の例には言いたいことがたくさんあります。

まず、中括弧で囲まれた初期化がどのように重みを持ち上げているかに注目してください。次にbegin(), end()、C ++ 11で追加されたジェネリックが登場します。次に、データのコンパレータとしてラムダ関数が登場します。ラムダ関数のパラメーターが宣言されていますautoこれはC ++ 14で追加されました。それ以前は、auto関数パラメーターに使用できませんでした。

角括弧でラムダ式を開始する方法に注意してください[]。それらはラムダのスコープを定義します—ローカル変数とオブジェクトに対してどれだけの権限を持っているか。

最新のC ++のこの素晴らしいリポジトリで定義されているように:

  • [] —何もキャプチャしません。したがって、ラムダ式内で外部スコープのローカル変数を使用することはできません。パラメータのみを使用できます。
  • [=]—スコープ内のローカルオブジェクト(ローカル変数、パラメーター)を値でキャプチャします。それらを使用することはできますが、変更することはできません。
  • [&] —参照によってスコープ内のローカルオブジェクト(ローカル変数、パラメーター)をキャプチャします。それらを変更できます。次の例のように。
  • [this]thisポインタを値でキャプチャします。
  • [a, &b]—参照aによって、値bによってオブジェクトをキャプチャします。

したがって、ラムダ関数内でデータを他の形式に変換する場合は、スコープを利用してラムダを使用できます。例えば:

上記の例で[factor]は、ラムダ式で値()によってローカル変数をキャプチャした場合、factor5行目で変更することはできません。単純に、それを行う権利がないためです。あなたの権利を悪用しないでください!?

最後に、val参照として使用していることに注意してください。これにより、ラムダ関数内の変更が実際にを変更することが保証されますvector

if&switch内の初期化ステートメント

私はそれを知った直後にC ++ 17のこの機能が本当に好きでした。

明らかに、変数の初期化を実行し、その条件をチェックすることができます—同時にif/switchブロック内で。これは、コードを簡潔でクリーンに保つのに非常に役立ちます。一般的な形式は次のとおりです。

if( init-statement(x); condition(x)) { // do some stuff here } else { // else has the scope of x // do some other stuff }

constexprによるコンパイル時にそれを行います

constexpr かっこいい!

評価する式があり、初期化するとその値は変更されないとします。値を事前に計算してから、マクロとして使用できます。または、C ++ 11が提供するように、を使用できますconstexpr

プログラマーは、プログラムの実行時間を可能な限り減らす傾向があります。したがって、コンパイラに実行させて実行時の負荷を軽減できる操作がある場合は、実行時間を改善できます。

上記のコードは、の非常に一般的な例ですconstexpr

フィボナッチ計算関数をとして宣言したのでconstexpr、コンパイラは事前計算できますfib(20)コンパイル時に。したがって、コンパイル後、行を置き換えることができます

const long long bigval = fib(20);

const long long bigval = 2432902008176640000;

渡された引数はconst値であることに注意してください。これは、宣言された関数の一つの重要なポイントであるconstexpr-渡された引数もする必要がありますconstexprconst。それ以外の場合、関数は通常の関数として動作します。つまり、コンパイル時に事前計算が行われません。

変数も可能constexprです。その場合、ご想像のとおり、これらの変数はコンパイル時に評価可能である必要があります。そうしないと、コンパイルエラーが発生します。

興味深いことに、後でC ++ 17で、constexpr-ifそしてconstexpr-lambda紹介されました。

タプル

と同じようにpairtupleさまざまなデータ型の固定サイズ値のコレクションです。

std::array代わりに使用する方が便利な場合がありtupleます。arrayプレーンCタイプの配列に似ていますが、C ++標準ライブラリのいくつかの機能があります。このデータ構造はC ++ 11で追加されました。

クラステンプレート引数の演繹

機能の非常に冗長な名前。アイデアは、C ++ 17から、テンプレートの引数の控除が標準のクラステンプレートでも発生するというものです。以前は、関数テンプレートでのみサポートされていました。

結果として、

std::pair user = {"M", 25}; // previous std::pair user = {"M", 25}; // C++17

控除の種類は暗黙的に行われます。これは、にとってさらに便利になりtupleます。

// previous std::tuple user ("M", "Chy", 25); // deduction in action! std::tuple user2("M", "Chy", 25);

上記のこの機能は、C ++テンプレートに精通していない場合は意味がありません。

スマートポインタ

ポインタは地獄のようになります。

C ++のような言語がプログラマーに提供する自由のために、自分の足を撃ち抜くのが非常に簡単になることがあります。そして多くの場合、ポインタが害の原因です。

幸い、C ++ 11では、生のポインターよりもはるかに便利なスマートポインターが導入されました。これらは、プログラマーが可能な場合にメモリーリークを解放することにより、メモリーリークを防ぐのに役立ちます。また、例外安全性も提供します。

この投稿では、C ++のスマートポインターについて書くことを考えました。しかし、どうやら、それらについては多くの重要な詳細があります。彼らは彼ら自身のポストに値する、そして私は確かに近い将来それらについてそれを書くつもりである。

それが今日のすべてです。C ++は、実際には最新バージョンの言語でさらに多くの新しい機能を追加したことを忘れないでください。興味があればぜひチェックしてみてください。これは、文字通りAwesome Modern C ++という名前のモダンC ++の素晴らしいリポジトリです。

アディオス!