36

我收到以下代码的警告有符号/无符号不匹配:

auto n = a.size();
for (auto i = 0; i < n; i++) {
}

问题是通过将 0 分配给i它变成int而不是size_t. 那么更好的是:

size_t n = a.size();
for (size_t i = 0; i < n; i++) {
}

或这个:

auto n = a.size();
for (size_t i = 0; i < n; i++) {
}

或者你有更好的解决方案?我更喜欢第一个,因为它更一致,它只是使用size_t而不是同时使用size_t,并且auto 用于相同的目的。

4

8 回答 8

51

基于范围的循环可能是更清洁的解决方案:

for (const auto& i : a)
{

}

这里,iconst对 container 元素的引用a

否则,如果您需要索引,或者如果您不想遍历整个范围,则可以使用decltype(a.size()).

for (decltype(a.size()) i = 0; i < a.size(); ++i) {
}
于 2013-07-06T17:08:18.023 回答
18

根据您想要在循环内执行的操作以及编译器的功能,基于范围的 for 循环可能是更好的解决方案。

在大多数情况下,您提出的所有解决方案都不错,差异很小 您的第一个解决方案实际上是更糟糕的选择,而这正是您的编译器告诉您的。第二种解决方案更好,但如果您想避免直接定义类型以简化或将来进行一些更改,您可以执行以下操作:

auto n = a.size();
for (decltype(n) i = 0; i < n; i++) {
}

通过这种方式,您可以绑定in类型以始终相互匹配。

于 2013-07-06T17:18:01.930 回答
6

如果你使用正确的文字,你会没事的:0U。auto 看到一个 int 类型的字面量,所以这是 i 的类型。添加 U ,它将看到一个无符号的 int 文字。否则,您会想像其他人建议的那样使用 decltype,特别是因为 sizeof(size_t) 可能大于 sizeof(int) (如果在 64 位长模式下运行,它在 Windows、OS X 等上)。

于 2013-07-06T17:26:31.947 回答
4

尽可能尝试 const 正确,我通常写:

const auto n(a.size());
for (auto i = decltype(n){0}; i < n; ++i)
{
}

这不是很简洁,但很明显,您希望将变量初始化为 0n的类型(并且nis const)。

于 2014-04-19T17:42:17.837 回答
2

讨论:

auto n = a.size();
for (auto i = n-n; i<n; ++i) {
}

请注意,对于小于 的类型int,减法结果扩大到int(称为整数提升)。

于 2013-07-09T22:54:16.233 回答
0

这是一个简单且更清洁的解决方案,可以让它发挥作用。

for(auto i: a)
{
}
于 2018-02-11T15:51:26.120 回答
0

在以下表达式的情况下,使用无符号类型会带来问题:

for (auto i = 0u; i < a.size() - k; ++i) ...

我提出了两种选择。第一个(编辑选择):

for (auto i = 0; i < static_cast<int>(a.size()); ++i) ...

如果您可以使用大小大于的类型size_t

for (auto i = 0ll; i < a.size(); ++i) ...

否则,如果带符号整数类型的操作数的类型可以表示无符号整数类型的操作数类型的所有值,则将无符号整数类型的操作数转换为有符号整数类型的操作数的类型。[expr.arith.conv]

于 2019-03-16T15:52:42.353 回答
-2
for(auto n = a.size(), i = 0; i != n; ++i) {
}

...如果您需要访问索引以及实际元素,这可能是最干净的解决方案。

更新:

for(auto n = a.size(), i = n*0; i != n; ++i) {
}

将是 Richard Smiths 评论的一种解决方法,尽管它看起来不再那么干净了。

于 2013-07-06T17:48:57.173 回答