181

私が C++ を学ぶために使用したすべての資料から、auto常に何の役にも立たない奇妙な保存期間指定子がありました。しかしつい最近、それ自体を型名として使用するコードに遭遇しました。好奇心から試してみたところ、たまたま割り当てたものの型を想定しています!

突然、STL イテレーターや、テンプレートを使用するものはすべて、10 倍簡単に記述できます。Python のような「楽しい」言語を使用しているように感じます。

このキーワードは私の人生のどこにありましたか?ビジュアルスタジオ専用とか移植不可とか言って、私の夢を打ち砕く気か?

4

8 に答える 8

183

autoは、C++ が C から「継承」したキーワードで、ほぼ永久に存在していましたが、可能な条件が 2 つしかなかったため、実質的に使用されることはありませんでした。許可されていないか、デフォルトで想定されていました。

推定型を意味するの使用はauto、C++11 で新しく導入されました。

同時に、テンプレートの型推定が関数テンプレートに対して機能するのと同じ方法で、型の型から の型auto x = initializerを推定します。次のような関数テンプレートを考えてみましょう:xinitializer

template<class T>
int whatever(T t) { 
    // point A
};

Tポイント A では、に渡されたパラメーターの値に基づいて型が に割り当てられていますwhatever。を実行するauto x = initializer;と、同じ型推定を使用して、初期化に使用されxた の型から の型が決定initializerされます。

これは、コンパイラが実装する必要がある型推論メカニズムのほとんどautoが既に存在し、C++98/03 の実装を試みるコンパイラのテンプレートに使用されていることを意味します。そのため、 のサポートを追加することautoは、本質的にすべてのコンパイラ チームにとって明らかにかなり簡単でした。これは非常に迅速に追加され、それに関連するバグもほとんどないようです。

この回答が最初に書かれたとき(2011年、C++ 11標準でインクが乾く前)autoは、すでにかなり移植可能でした。今日では、すべての主流のコンパイラ間で完全に移植可能です。それを回避する唯一の明白な理由は、C コンパイラと互換性のあるコードを書く必要がある場合、またはそれをサポートしていないことがわかっているニッチなコンパイラをターゲットにする必要がある場合です (たとえば、まだコードを書いている人は少数です)。 MS-DOS の場合、Borland、Watcom などのコンパイラを使用しており、これらのコンパイラは何十年も大幅なアップグレードを行っていません)。主流のコンパイラのかなり最新のバージョンを使用している場合でも、それを避ける理由はまったくありません。

標準の最近のリビジョンでは、auto使用できる新しい場所がいくつか追加されています。C++14 以降でautoは、パラメーターの型としてラムダを使用できます。

    [](auto s) { return s + 1; }

これは基本的に上記の例と同じことを行います。明示的に構文を使用していませんがtemplate、これは基本的に、パラメーターの型を推測し、その型でテンプレートをインスタンス化するテンプレートです。

これは便利で便利だったので、C++20 ではラムダ関数だけでなく、通常の関数にも同じ機能が追加されました。

しかし、これまでと同様に、C++98 以降の関数テンプレートと同じ基本的な型推論メカニズムを使用することになります。autoより多くの場所でより便利に使用できるようになりますが、根底にある重労働は同じままです。

于 2011-09-28T00:28:56.690 に答える
28

これは、一般的に役に立たないキーワードを取り、新しいより優れた機能を提供するだけです。これは C++11 の標準であり、一部の C++11 をサポートするほとんどの C++ コンパイラでもサポートされます。

于 2011-09-28T00:03:20.830 に答える
17

変数の場合、宣言されている変数の型がその初期化子から自動的に推測されることを指定します。関数の場合、戻り値の型が末尾の戻り値の型であるか、その return ステートメントから推定されることを指定します (C++14以上)。

構文

auto variable initializer   (1) (since C++11)

auto function -> return type    (2) (since C++11)

auto function   (3) (since C++14)

decltype(auto) variable initializer (4) (since C++14)

decltype(auto) function (5) (since C++14)

auto :: (6) (concepts TS)

cv(optional) auto ref(optional) parameter   (7) (since C++14)

説明

  1. ブロック スコープ、名前空間スコープ、for ループの初期化ステートメントなどで変数を宣言する場合、キーワード auto を型指定子として使用できます。

    初期化子の型が決定されると、コンパイラは、関数呼び出しからのテンプレート引数推定のルールを使用して、キーワード auto を置き換える型を決定します (詳細については、テンプレート引数推定#その他のコンテキストを参照してください)。キーワード auto には、型推論に関与する const や & などの修飾子を付けることができます。たとえば、 が与えられた場合、関数呼び出しがコンパイルされた場合const auto& i = expr;、 i の型は架空のテンプレートの引数 u の型とまったく同じです。したがって、 auto&& は、範囲ベースの for ループで使用される初期化子に従って、左辺値参照または右辺値参照のいずれかとして推定される場合があります。template<class U> void f(const U& u)f(expr)

    auto を使用して複数の変数を宣言する場合、推定される型が一致する必要があります。たとえば、宣言は整形式ですがauto i = 0, d = 0.0;、宣言auto i = 0, *p = &i;は整形式で、auto は int として推定されます。

  2. 末尾の戻り値の型の構文を使用する関数宣言では、キーワード auto は自動型検出を実行しません。構文の一部としてのみ機能します。

  3. 末尾の戻り値の型の構文を使用しない関数宣言では、キーワード auto は、戻り値の型がテンプレート引数推定の規則を使用して return ステートメントのオペランドから推定されることを示します。

  4. 変数の宣言された型が の場合decltype(auto)、キーワード auto はその初期化子の式 (または式リスト) に置き換えられ、実際の型は decltype の規則を使用して推定されます。

  5. 関数の戻り値の型が宣言されているdecltype(auto)場合、キーワード auto はその return ステートメントのオペランドに置き換えられ、実際の戻り値の型は decltype の規則を使用して推定されます。

  6. auto:: 形式のネストされた名前指定子は、制約付き型のプレースホルダー演繹の規則に従って、クラスまたは列挙型に置き換えられるプレースホルダーです。

  7. ラムダ式のパラメーター宣言。(C++14以上) 関数のパラメータ宣言。(コンセプトTS)

ノート

C++11 までは、auto は保存期間指定子の意味を持っていました。のように、auto 変数と関数を 1 つの宣言に混在さauto f() -> int, i = 0;せることはできません。

詳細情報: http://en.cppreference.com/w/cpp/language/auto

于 2016-06-30T14:04:25.187 に答える
13

この機能は、あなたの人生全体ではありませんでした。2010 バージョン以降、Visual Studio でサポートされています。これは C++11 の新しい機能であるため、Visual Studio 専用ではなく、移植可能です。ほとんどのコンパイラはすでにサポートしています。

于 2011-09-28T00:02:32.387 に答える
4

どこにも行きません...これは、C++11 の実装における新しい標準 C++ 機能です。そうは言っても、オブジェクト宣言を簡素化し、特定の呼び出しパラダイム (つまり、範囲ベースの for ループ) の構文をクリーンアップするための素晴らしいツールですが、使いすぎたり乱用したりしないでください:-)

于 2011-09-28T00:06:05.743 に答える