注この質問は、C++ 11が批准される前で、
auto
キーワードの意味が大幅に変更される前の2009年に最初に投稿されました。提供される回答は、auto
のC++ 03の意味(指定されたストレージクラスであること)に関連するonlyであり、C++ 11の意味ではありませんauto
-それは自動型推論です。 C++ 11auto
をいつ使用するかについてのアドバイスを探している場合、この質問はその質問には関係ありません。
長い間、Cでstatic
キーワードを使用する理由はないと思っていました。ブロックスコープの外側で宣言された変数は暗黙的にグローバルだからです。それから、ブロックスコープ内で変数をstatic
として宣言すると永続的な期間が与えられ、ブロックスコープ外で(プログラムスコープで)宣言するとファイルスコープになることがわかりました(アクセスできるのはそのコンパイル単位)。
そのため、私は(おそらく)まだ完全には理解していないキーワードauto
を1つだけ残しています。 「ローカル変数」以外の意味はありますか?あなたがそれを使いたいところはどこでも、それはあなたのために暗黙のうちにされませんか? auto
変数はプログラムスコープでどのように動作しますか? static auto
ファイルスコープの変数?このキーワードには、完全性のために存在する以外の目的はありますか?
auto
はストレージクラス指定子であり、static
、register
、およびextern
も同様です。宣言では、これら4つのうち1つしか使用できません。
ローカル変数(static
なし)には自動保存期間があります。つまり、定義の開始からブロックの終了まで生存します。とにかくそれがデフォルトであるので、それらの前にautoを置くことは冗長です。
C++で使用する理由はわかりません。暗黙のintルールを持つ古いCバージョンでは、次のようにそれを使用して変数を宣言できます。
int main(void) { auto i = 1; }
i
がスコープ内にある場合に、有効な構文にするか、割り当て式から明確にする。ただし、これはC++では機能しません(型を指定する必要があります)。面白いことに、C++標準は次のように書いています。
ブロックスコープでstorage-class-specifierなしで宣言されたオブジェクト、または関数パラメーターとして宣言されたオブジェクトには、デフォルトで自動ストレージ期間があります。 [注:したがって、自動指定子はほとんど常に冗長であり、あまり使用されません。 autoの使用法の1つは、宣言文と式文(6.8)を明示的に区別することです。 —終了ノート]
a
からint
へのキャスト、または冗長なかっこを持つタイプa
の変数int
の宣言のいずれかである可能性がある次のシナリオを参照しますa
の周り。常に宣言と見なされるため、auto
はここでは有用なものを追加しませんが、代わりに人間にとっては追加します。しかし、再び、人間はa
の周りの余分な括弧を削除する方が良いでしょう、私は言うでしょう:
int(a);
auto
の新しい意味がC++ 0xで届くと、コードでC++ 03の意味でそれを使用することはできません。
C++ 11では、auto
には新しい意味があります。これにより、変数の型を自動的に推測できます。
なぜこれが便利なのですか?基本的な例を考えてみましょう。
std::list<int> a;
// fill in a
for (auto it = a.begin(); it != a.end(); ++it) {
// Do stuff here
}
auto
は、std::list<int>::iterator
型の反復子を作成します。
これにより、いくつかの非常に複雑なコードがはるかに読みやすくなります。
もう一つの例:
int x, y;
auto f = [&]{ x += y; };
f();
f();
そこで、auto
は、ラムダ式を変数に格納するために必要な型を推測しました。ウィキペディアには、良いものがあります 主題に関する報道
Autoキーワードには現時点では何の目的もありません。ローカル変数のデフォルトのストレージクラスを再定義するだけで、本当に便利な代替手段はstatic
です。
C++ 0xでは 真新しい意味 です。それはあなたにそれがどれほど役に立たないかについてのいくらかのアイデアを与えます!
GCCでは、ネストされた関数に対してauto
を特別に使用します- here を参照してください。
定義する前に呼び出したい関数をネストしている場合は、auto
で宣言する必要があります。
「auto」は、変数(メモリまたはレジスタ)を配置する場所を自分で決定するようにコンパイラに指示します。その類似物は「レジスタ」であり、おそらくレジスタにそれを保持しようとするようコンパイラーに指示します。現代のコンパイラは両方を無視するので、あなたもそうすべきです。
このキーワードを使用して、スタックベースのプロセッサで変数がスタックに配置されることが機能にとって重要である場合を明示的に文書化します。この関数は、関数(または割り込みサービスルーチン)から戻る前にスタックを変更するときに必要になる場合があります。この場合、私は宣言します:
auto unsigned int auiStack[1]; //variable must be on stack
そして、変数の外部にアクセスします:
#define OFFSET_TO_RETURN_ADDRESS 8 //depends on compiler operation and current automatics
auiStack[OFFSET_TO_RETURN_ADDRESS] = alternate_return_address;
したがって、auto
キーワードは意図を文書化するのに役立ちます。
Stroustrupによれば、「The C Programming Language」(C 11をカバーする第4版)で、「auto」の使用には次の主な理由があります(セクション2.2.2)(Stroustrupの言葉は引用されています)。
1)
この定義は、コードの読者に型を明確に見えるようにする大きな範囲にあります。
「auto」とその必要なイニシャライザを使用すると、変数の型を一目で知ることができます!
2)
変数の範囲または精度について明示的にしたい(例:floatではなくdouble)
私の意見では、ここに当てはまるケースは次のようなものです。
double square(double d)
{
return d*d;
}
int square(int d)
{
return d*d;
}
auto a1 = square(3);
cout << a1 << endl;
a1 = square(3.3);
cout << a1 << endl;
3)
'auto'を使用すると、冗長性がなくなり、長い型名が書き込まれます。
テンプレート化されたイテレータからの長い型名を想像してください:
(セクション6.3.6.1のコード)
template<class T> void f1(vector<T>& arg) {
for (typename vector<T>::iterator p = arg.begin(); p != arg.end(); p)
*p = 7;
for (auto p = arg.begin(); p != arg.end(); p)
*p = 7;
}
古いコンパイラでは、autoはローカル変数を宣言する1つの方法でした。 autoキーワードなどを使用せずに、Turbo Cなどの古いコンパイラでローカル変数を宣言することはできません。
C++ 0xのautoキーワードの新しい意味は、MSDNのChannel 9サイトにあるSTLに関する自由に閲覧/ダウンロード可能なビデオレクチャーでMicrosoftのStephan T. Lavavejによって非常にうまく説明されています here 。
講義全体を見る価値はありますが、自動キーワードに関する部分は約29分目(およそ)です。
「ローカル変数」以外の「自動」には他の意味がありますか?
C++ 03ではありません。
それを行うことは、あなたがそれを使いたいところにあなたのために暗黙のうちにされませんか?
C++ 03では、何もありません。
自動変数はプログラムスコープでどのように動作しますか?ファイルスコープの静的自動変数はどうですか?
キーワードは、関数/メソッド本体の外部では許可されていません。
このキーワードには、完全性のために存在する以外の目的([C++ 03])がありますか?
驚くべきことに、はい。 C++の設計基準には、Cとの高度な下位互換性が含まれていました。Cにはこのキーワードがあり、C++で禁止または意味を再定義する本当の理由はありませんでした。そのため、目的はCとの非互換性を1つ少なくすることでした。
このキーワードは、完全を期すために存在する以外の目的でCにありますか
私は最近1つだけを学びました。Bからの古代プログラムの移植の容易さ。Cは構文がCのそれに非常に類似したBと呼ばれる言語から発展しました。しかし、Bにはまったく型がありませんでした。 Bで変数を宣言する唯一の方法は、そのストレージタイプ(auto
またはextern
)を指定することでした。このような:
auto i;
この構文はまだCで機能し、次と同等です。
int i;
cでは、ストレージクラスのデフォルトはauto
であり、タイプのデフォルトはint
であるためです。 Bで作成され、Cに移植されたすべてのプログラムは、その時点で文字通りauto
変数でいっぱいだったと思います。
C++ 03では、Cスタイルの暗黙のintは許可されなくなりましたが、暗黙のintとは異なり、構文に問題を引き起こすことはわかっていなかったため、もはやまったく使用されないauto
キーワードを保持しました。 C.