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


85

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

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

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

回答:


74

autoストレージクラス指定子は、ありますstaticregisterそしてexternあまりにも。宣言では、これら4つのうち1つしか使用できません。

ローカル変数(なし static)には自動保存期間があります。つまり、定義の開始からブロックの終了まで存続します。とにかくそれがデフォルトであるため、それらの前に自動を置くことは冗長です。

C ++で使用する理由はわかりません。暗黙のintルールを持つ古いCバージョンでは、次のようにそれを使用して変数を宣言できます。

int main(void) { auto i = 1; }

有効な構文にするか、場合に応じて代入式から明確にするため i、スコープ内。しかし、これはとにかくC ++では機能しません(タイプを指定する必要があります)。面白いことに、C ++標準は次のように書いています。

ブロックスコープでstorage-class-specifierなしで宣言されたオブジェクト、または関数パラメーターとして宣言されたオブジェクトには、デフォルトで自動ストレージ期間があります。[注:したがって、自動指定子はほとんどの場合冗長であり、あまり使用されません。autoの使用法の1つは、宣言ステートメントと式ステートメント(6.8)を明示的に区別することです。—エンドノート]

これは、次のシナリオを参照します。これは、atoのキャスト、intまたはの前後に冗長な括弧aがあるタイプの変数の宣言のいずれかです。これは常に宣言であると見なされるため、ここでは有用なものは何も追加しませんが、代わりに人間にとっては追加します。しかし、繰り返しになりますが、人間は周りの冗長な括弧を削除したほうがよいでしょう、と私は言います:intaautoa

int(a);

autoC ++ 0xで到着するという新しい意味があるので、コードでC ++ 03の意味でそれを使用することはお勧めしません。


4
C ++コンパイラは、関数からの戻り値に対して暗黙のintを使用することがよくありました。これは、標準の前のARMの時代に...
帝国の

1
関数を前方宣言するのを忘れたことをコンパイラーが伝える方法として認識しました。関数の使用法は、暗黙のintのために、宣言された方法とは異なっていたことがわかります。
カーソンマイヤーズ

29
最良の部分は、プログラマーが「int」(3文字)を書かないようにするために「auto」(4文字)を書いていたことです。
Max Lybbert 2009年

30
@ Max-ねえ、多くの人が「WorldWideWeb」の略語として「double-u-double-u-double-u」と言います。
Daniel Earwicker 2009年

3
@smichakいいえ、「volatile」は型修飾子です。値を格納する場所を決定するのではなく、揮発性修飾型のオブジェクトへの書き込みおよびオブジェクトからの読み取りの動作を変更します。揮発性修飾スタック変数(自動ストレージクラス)と、揮発性修飾静的ストレージ期間変数(ローカルの「静的」ストレージクラス、非ローカル変数)があります。それを除けば、「registervolatile」が有効な組み合わせであるかどうかはわかりません:)
Johannes Schaub --litb 2012年

86

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ラムダ式を変数に格納するために必要なタイプを推定しました。ウィキペディアは、このテーマについて十分に取り上げています。


4
これがautoの優れた使用法であるかどうかはまだわかりません。コードは、書きやすくなく、読みやすくする必要があります。
ダンダン2012年

38
私はあなたのことを知りませんが、これはイテレータタイプのスパムよりもはるかに読みやすいと思います。
Overv 2012年

17
また、ある理由でクラスをlist <int>から他のクラスに変更することにした場合、すべてのイテレータ宣言を検索して変更する必要はありません。
roslav 2012

2
@KarateSnowMachine:constが必要な場合は、「auto」ではなく「constauto」を使用します。
ダースハッピーフェイス2013年

4
@darthconst auto it = a.begin();iterator、ではなくconstを返しますconst_iterator。それでも要素を変更++itする必要がありますが、コンパイルに失敗します。を取得するにはconst_iterator、次を使用しますauto it = a.cbegin();
fredoverflow 2013

35

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

これは、C ++ 0xではまったく新しい意味を持っています。それはあなたにそれがどれほど役に立たなかったかのいくつかの考えを与えます!


1
ああ、それは今まで役に立たなかった。私は新しい意味が好きです。これにより、一部のコードの冗長性と冗長性が大幅に低下します。
カーソンマイヤーズ

はい、C#で同等のものを使用した場合、おそらく大きな違いが生じます。C ++では、型が非常に複雑で手作業で書き出すことを意図していない式テンプレートを使用している場合はさらにそうです。
Daniel Earwicker 2009年

7

GCCには、autoネストされた関数のための特別な用途があります-ここを参照してください

定義の前に呼び出すネストされた関数がある場合は、で宣言する必要がありますauto


これは、コンパイラに依存しますが、autoの優れた実装です。調査に感謝します:)
Carson Myers

3

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


1
正確ではありません。「register」で宣言した場合、コンパイラは変数にaddress-of演算子(&foo)を使用できません。これは、メモリ内のどこにも存在しないため(したがって、アドレスがないため)です。
ティムCAS

3

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

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


キーワードは実際にはスタック配置を強制しないので、これは単にシグナリングの意図であると思います。単にそれを省略するだけでは不十分です。
underscore_d

2

Stroustrupによると、「The C Programming Language」(第4版、C 11をカバー)では、「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;
}

1

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


1

C ++ 0xでのautoキーワードの新しい意味は、MicrosoftのStephan T. Lavavejによって、MSDNのチャネル9サイトにあるSTLに関する無料で表示/ダウンロード可能なビデオ講義で非常にうまく説明されています

講義全体を見る価値はありますが、autoキーワードの部分は約29分(約)です。


0

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

C ++ 03にはありません。

あなたがそれを使いたいと思うところならどこでもあなたのために暗黙のうちに行われていないことは何ですか?

C ++ 03では、何もありません。

自動変数はプログラムスコープでどのように動作しますか?ファイルスコープの静的自動変数はどうですか?

関数/メソッド本体の外部ではキーワードを使用できません。

このキーワードは、完全を期すために存在する以外に、[C ++ 03で]目的がありますか?

驚いたことに、はい。C ++の設計基準には、Cとの高度な下位互換性が含まれていました。Cにはこのキーワードがあり、C ++でそれを禁止したり、その意味を再定義したりする本当の理由はありませんでした。したがって、目的はCとの非互換性を1つ減らすことでした。

このキーワードは、完全を期すために存在する以外に、Cで何か目的がありますか?

私は最近1つだけ学びました:Bからの古代プログラムの移植の容易さ。Cは構文がCの構文と非常に似ているBと呼ばれる言語から進化しました。しかし、Bにはタイプがまったくありませんでした。Bで変数を宣言する唯一の方法は、そのストレージタイプ(autoまたはextern)を指定することでした。このような:

自動i;

この構文はCでも機能し、同等です

int i;

Cでは、ストレージクラスのデフォルトは。autoであり、タイプのデフォルトはint。であるためです。Bで始まり、Cに移植されたすべてのプログラムは、文字通りいっぱいだったと思います。autoは、当時変数でと思います。

C ++ 03は、Cスタイルの暗黙のintを許可しなくなりましたが、暗黙のintautoとは異なり、Cの構文に問題を引き起こすことが知られていないため、もはや正確に役に立たないキーワードを保持しました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.