【问题标题】:Auto failed for vector size向量大小自动失败
【发布时间】:2018-05-26 11:52:45
【问题描述】:

我正在尝试使用auto 来推断类型。

for (auto i = remaining_group.size() - 1; i >= 0; --i) {
    std::cout << i;
}

我得到了非常大的数字,例如 18446744073709534800,这是意料之外的。当我将 auto 更改为 int 时,这是我期望的介于 0 和 39 之间的数字。

auto 会在这里失败吗?

remaining_group 的类型是 std::vector&lt;lidar_point&gt;lidar_point 是类似结构:

struct LidarPoint {
  float x;
  float y;
  float z;
  uint8_t field1;
  double field2;
  uint8_t field3;
  uint16_t field4;
}

【问题讨论】:

  • remainug_group 是如何定义的?另外 - 也许大小是 0?
  • size() 返回什么类型?
  • 如果size 是无符号的,那么条件i &gt;= 0 总是为真,你最终会得到一个整数下溢。
  • Using auto in loops c++的可能重复
  • size_t而不是auto只需要2个字符,但它带来的明确性非常值得

标签: c++ c++11 vector auto


【解决方案1】:

当使用auto 时,i 的类型将是std::vector::size_type,这是一个无符号整数类型。这意味着条件i &gt;= 0; 将始终为true,如果overflow 发生,您将得到一些大数字。

无符号整数运算总是模 2n 其中 n 是该特定整数中的位数。例如。对于unsigned int,将UINT_MAX 加一得到​0,从0 减一得到UINT_MAX

【讨论】:

  • 谢谢!这是正确的答案。在这种情况下使用 auto 真的需要小心!
  • @songyuanyao • 静态演员表不应包括- 1 部分。考虑当剩余组为空时会发生什么,大小为 0。
  • @Eljay 正确。
  • @Alex 如果您坚持使用autoauto i = static_cast&lt;int&gt;(remaining_group.size()) - 1,这是一个冗长的解决方法。
  • @Swift-FridayPie 我没听懂; i 的类型仍然是无符号整数类型? LIVE
【解决方案2】:

问题的简单再现:

#include <iostream>

size_t size()  {return 1;}

int main() {
   for (auto i = size() - 1; i >= 0; --i) {
    std::cout << i << std::endl;
   }
}

size()得到类型size_t和字面常量1会被提升为size_t,结果auto会变成size_t,它不能小于零,导致无限循环和下溢i

【讨论】:

  • 哦,伙计,整数提升。我本来希望最终类型会被签名,但是......促销规则。
【解决方案3】:

如果需要反向索引循环,请使用operator --&gt;

当你编写一个普通的索引循环时,你用0size&lt;编写它。

当你编写一个正常的反向索引循环时,事情变得有点不稳定:你需要size - 1&gt;=0,并且你不能使用 unsigned 索引,因为 unsigned i 总是 &gt;= 0 所以你的检查 i &gt;= 0 总是返回 true,你的循环可以永远运行。

使用伪运算符“goes to”,可以使用0size&gt;编写反向索引循环,i是有符号还是无符号都没有关系:

for (auto i = a.size(); i --> 0; ) //or just i--, or i --> 1, i --> 10...
    std::cout << i << ' ';

【讨论】:

    猜你喜欢
    • 2019-07-02
    • 2018-07-07
    • 1970-01-01
    • 1970-01-01
    • 2016-09-01
    • 2016-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多