-4

可能重复:
C++0x 自动关键字多少是太多了

我发现在临界点附近使用“自动”可能会导致一些问题。

这是示例代码:

#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。

我应该避免在临界点附近使用“自动”吗?或者我如何在这里适当地使用“自动”?

更新:有人说“尽可能使用汽车”。在这个线程中你告诉我。我认为这不太对。“long long int”类型更适合这里的“int”类型。我想知道哪里可以安全地使用“自动”,哪里不能。

更新 2:Herb Sutter文章的解决方案 4(b)应该已经回答了这个问题。

4

4 回答 4

0

如果它是正确的,你应该只依靠类型推导来计算你的变量的类型。在这里,编译器推断它是一个int,就标准而言这是正确的,但是您的具体问题需要具有更大范围的另一种类型。当您使用 时auto,您是在说“编译器最了解”,但编译器并不总是知道一切。

你不会auto在这里使用,就像你不会使用int. 你可以让你的文字有更高的等级(坚持LLL在它之后——尽管它们不能保证比你的更大int),然后auto会推导出一个更大的整数类型。

更不用说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

你对auto. 您的期望是auto自动推断出最适合您要对变量执行的操作的类型。这是语义分析,编译器不应该这样做(大多数情况下,他们不能)。他们无法期待您稍后在程序中使用您声明的变量的方式。

关键字只会让auto您免于在左侧显式写出右侧出现的表达式类型的负担,避免可能的冗余和与之相关的所有问题(如果右侧表达式的类型发生变化怎么办?)

这就是说,所有其他答案都是正确的:如果您希望变量i不溢出,则应为其分配一个long long文字(使用LL后缀)。

于 2012-12-29T13:09:00.023 回答