C ++ autoキーワード。なぜそれは魔法なのですか?


144

私がC ++を学ぶために使用したすべての資料から、auto常に何の目的も果たさない奇妙なストレージ期間指定子でした。しかし、つい最近、それ自体を型名として使用するコードに遭遇しました。好奇心から私はそれを試しました、そしてそれは私がそれに偶然割り当てるもののタイプを想定しています!

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

このキーワードは私の人生のどこにありましたか?それはビジュアルスタジオ専用であるか、ポータブルでないと言って、私の夢を打ち砕いてくれませんか?


18
そうではありません。マジック。それは新しいです(ああ、なんて悪い駄洒落)。今は非同期が未来(gasp
sehe

回答:


149

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

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

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

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

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

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

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


23

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


ああ!ああ、C ++はそれ自体で変化する可能性があるものだとは考えていませんでした。私は彼らがこのC ++ 11で他に何を追加したかを調べなければならないだろう、私はC ++ 0xの少しを聞いたが、あまり深く掘り下げたことはない。
アン・クイン

7
@Clairvoire C ++ 0xは暫定的な名前でした。今月公開され、C ++ 11となりました。
R.マルティーニョフェルナンデス

13

変数の場合、宣言されている変数の型がその初期化子から自動的に推定されることを指定します。関数の場合、戻り値の型が末尾の戻り値の型であるか、またはその戻りステートメントから推定されることを指定します(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の型とまったく同じtemplate<class U> void f(const U& u)です。f(expr)コンパイルされました。したがって、auto &&は、範囲ベースのforループで使用される初期化子に従って、左辺値参照または右辺値参照のいずれかとして推定できます。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にはストレージ期間指定子のセマンティクスがありました。のように、1つの宣言に自動変数と関数を混在さauto f() -> int, i = 0;せることはできません。

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


11

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


3

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


3

autoキーワードは、宣言されている変数の型がその初期化子から自動的に差し引かれるように指定します。関数の場合、戻り値の型が自動の場合、実行時に戻り値の型式によって評価されます。

イテレータを使用する必要がある場合に非常に便利です。たとえば、以下のコードでは、イテレータ構文全体を記述する代わりに、「auto」を使用できます。

int main() 
{ 

// Initialize set 
set<int> s; 

s.insert(1); 
s.insert(4); 
s.insert(2); 
s.insert(5); 
s.insert(3); 

// iterator pointing to 
// position where 2 is 
auto pos = s.find(3); 

// prints the set elements 
cout << "The set elements after 3 are: "; 
for (auto it = pos; it != s.end(); it++) 
    cout << *it << " "; 

return 0; 
}

これが「auto」キーワードの使用方法です


0

それは、特定の関数に渡されるすべての変数タイプのコードを記述する必要性を減らす能力です。Pythonベースのprint()関数をCベースで考えてみましょう。

#include <iostream>
#include <string>
#include <array>

using namespace std;

void print(auto arg) {
     cout<<arg<<" ";
}

int main()
{
  string f = "String";//tok assigned
  int x = 998;
  double a = 4.785;
  string b = "C++ Auto !";
//In an opt-code ASCII token stream would be iterated from tok's as:
  print(a);
  print(b);
  print(x);
  print(f);
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.