-4

重複の可能性:
C ++0xautoキーワードでは多すぎます

重要なポイントの近くで「自動」を使用すると、問題が発生する可能性があります。

これはサンプルコードです:

#include <iostream>
#include <typeinfo>
#include <limits>

using std::cout;
using std::endl;
using std::numeric_limits;
using std::cerr;

int main() {
   auto i = 2147483647 /* numeric_limits<int>::max() */ ;
   cout << "The type of i is " << typeid(i).name() << endl;

   int count = 0;
   for (auto i = 2147483647; 
        i < 2147483657 /* numeric_limits<int>::max() + 10 */ ; ++i) {
       cout << "i = " << i << " " << endl;

       if (count > 30) {
           cerr << "Too many loops." << endl;
           break;
       }
       ++count;
   }

   return 0;
}

「auto」は「i」のタイプが整数であると判断しますが、整数の上限は2147483647であり、簡単にオーバーフローします。

これがIdeone(gcc-4.5.1)LWS(gcc-4.7.2)の出力です。それらは異なります。「i」はIdeone(gcc-4.5.1)のループでは2147483647のままであり、 LWS(gcc-4.7.2)ではオーバーフローします。しかし、それらのどれも期待される結果ではありません:10サイクル、毎回+1。

重要なポイントの近くで「自動」を使用することは避けるべきですか?または、ここで「自動」を適切に使用するにはどうすればよいですか?

更新:誰かが「あなたができるところならどこでも自動を使う」と言います。このスレッドであなたは私に言います。私はそれが完全に正しいとは思いません。ここでは、「longlongint」と入力する方が「int」と入力する方が適切です。どこで「自動」を安全に使えるのか、どこで使えないのかしら。

更新2:ハーブサッターによる記事の解決策4(b)が質問に答えているはずです。

4

4 に答える 4

0

変数の型が正しくなる場合にのみ、型の推定に依存して変数の型を計算する必要があります。ここで、コンパイラーはそれがであると推論しますint。これは標準に関する限り正しいですが、特定の問題には、より広い範囲の別のタイプが必要です。を使用するautoと、「コンパイラが最もよく知っている」と言っていますが、コンパイラが常にすべてを知っているわけではありません。

autoを使用しないのと同じように、ここでは使用しませんint。リテラルのランクを高くして(スティックLまたはそれLL以降-自分よりも大きくなることは保証されていませんがintauto、より大きな積分型を推測することができます。

言うまでもなくauto、この場合、実際には何も節約できません。auto通常、長くて醜いタイプや知らないタイプを入力しないようにするために使用されます。この場合、タイプは長くて醜いものではなく、あなたはそれを知っています。

于 2012-12-29T13:02:10.057 に答える
0

auto単なる構文糖衣です。これは型ではなく、右側がどの型であるかを推測し、それによってその変数の型を決定するだけです。

リテラルを指定すると、コンパイラによって指定されたデフォルトの型が推測されます。
実際のタイプが何であるかを知る必要があります。

于 2012-12-29T13:04:02.210 に答える
0

intタイプを明示的に変更しない限り、数値リテラル(小数点なし)は常にです。

int x = 2147483657; // 2147483657 is treated as an int.
                    // If it does not fit tough it will be truncated
                    // according to standard rules.

long x = 2147483657L; // The L suffix tells the compiler to treat it as a long.
                      // Here you will get the correct value assuming long is larger than int.

あなたの場合:

for(auto i = 2147483647;i < 2147483657;) // is not going to work as i is always 
                                         // an int and literal overflows.

// Try correct types:

for(auto i = 2147483647L; i < 2147483657L;++i) //Now it should work correctly.
于 2012-12-29T13:04:05.687 に答える
0

に期待しすぎていますautovariableに対して実行する操作に最適なauto型を自動的に推測することが期待されます。これはセマンティック分析であり、コンパイラがそれを行うことは期待されていません(ほとんどの場合、できません)。彼らは、後でプログラムで宣言した変数をどのように使用するかを楽しみにすることができません。

このautoキーワードは、右側に表示される式の型を左側に明示的に記述するという負担からあなたを救うだけであり、可能な冗長性とそれに関連するすべての問題を回避します (右側の式の型が変更された場合はどうなるでしょうか?)

これは、他のすべての答えが正しいということです。変数iがオーバーフローしないようにする場合は、変数にlong longリテラルを割り当てる必要があります(LL接尾辞を使用)。

于 2012-12-29T13:09:00.023 に答える