web-dev-qa-db-ja.com

C ++ 03で「auto」キーワードを使用する理由はありますか?

この質問は、C++ 11が批准される前で、autoキーワードの意味が大幅に変更される前の2009年に最初に投稿されました。提供される回答は、autoのC++ 03の意味(指定されたストレージクラスであること)に関連するonlyであり、C++ 11の意味ではありませんauto-それは自動型推論です。 C++ 11 autoをいつ使用するかについてのアドバイスを探している場合、この質問はその質問には関係ありません。

長い間、Cでstaticキーワードを使用する理由はないと思っていました。ブロックスコープの外側で宣言された変数は暗黙的にグローバルだからです。それから、ブロックスコープ内で変数をstaticとして宣言すると永続的な期間が与えられ、ブロックスコープ外で(プログラムスコープで)宣言するとファイルスコープになることがわかりました(アクセスできるのはそのコンパイル単位)。

そのため、私は(おそらく)まだ完全には理解していないキーワードautoを1つだけ残しています。 「ローカル変数」以外の意味はありますか?あなたがそれを使いたいところはどこでも、それはあなたのために暗黙のうちにされませんか? auto変数はプログラムスコープでどのように動作しますか? static autoファイルスコープの変数?このキーワードには、完全性のために存在する以外の目的はありますか?

84
Carson Myers

autoはストレージクラス指定子であり、staticregister、および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は、ラムダ式を変数に格納するために必要な型を推測しました。ウィキペディアには、良いものがあります 主題に関する報道

86
std''OrgnlDave

Autoキーワードには現時点では何の目的もありません。ローカル変数のデフォルトのストレージクラスを再定義するだけで、本当に便利な代替手段はstaticです。

C++ 0xでは 真新しい意味 です。それはあなたにそれがどれほど役に立たないかについてのいくらかのアイデアを与えます!

34

GCCでは、ネストされた関数に対してautoを特別に使用します- here を参照してください。

定義する前に呼び出したい関数をネストしている場合は、autoで宣言する必要があります。

7
qrdl

「auto」は、変数(メモリまたはレジスタ)を配置する場所を自分で決定するようにコンパイラに指示します。その類似物は「レジスタ」であり、おそらくレジスタにそれを保持しようとするようコンパイラーに指示します。現代のコンパイラは両方を無視するので、あなたもそうすべきです。

3
T.E.D.

このキーワードを使用して、スタックベースのプロセッサで変数がスタックに配置されることが機能にとって重要である場合を明示的に文書化します。この関数は、関数(または割り込みサービスルーチン)から戻る前にスタックを変更するときに必要になる場合があります。この場合、私は宣言します:

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キーワードは意図を文書化するのに役立ちます。

3
luke

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;
}
2
wesley.mesquita

古いコンパイラでは、autoはローカル変数を宣言する1つの方法でした。 autoキーワードなどを使用せずに、Turbo Cなどの古いコンパイラでローカル変数を宣言することはできません。

1
chaz

C++ 0xのautoキーワードの新しい意味は、MSDNのChannel 9サイトにあるSTLに関する自由に閲覧/ダウンロード可能なビデオレクチャーでMicrosoftのStephan T. Lavavejによって非常にうまく説明されています here

講義全体を見る価値はありますが、自動キーワードに関する部分は約29分目(およそ)です。

1
Sabuncu

「ローカル変数」以外の「自動」には他の意味がありますか?

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.

0
Jirka Hanika