我收到以下代码的签名/未签名不匹配警告:
auto n = a.size();
for (auto i = 0; i < n; i++) {
}
问题是,通过为i
分配0,它变为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
出于同样的目的。
答案 0 :(得分:43)
基于范围的循环可能是一个更清洁的解决方案:
for (const auto& i : a)
{
}
此处,i
是对容器const
元素的a
引用。
否则,如果您需要索引,或者如果您不想遍历整个范围,则可以使用decltype(a.size())
获取类型。
for (decltype(a.size()) i = 0; i < a.size(); ++i) {
}
答案 1 :(得分:19)
根据您在循环内部要做的事情以及编译器的功能,基于范围的for循环可能是更好的解决方案。
在大多数情况下,您提出的所有解决方案都不错,但存在细微差别 你的第一个解决方案实际上是更糟糕的选择,这正是你的编译器告诉你的。 第二种解决方案更好,但如果您想避免直接定义类型以简化或未来的更改,您可以执行以下操作:
auto n = a.size();
for (decltype(n) i = 0; i < n; i++) {
}
这样,您可以将i
和n
类型绑定为始终相互匹配。
答案 2 :(得分:5)
如果您使用了正确的文字,那就没关系:0U。 auto看到int类型的文字,所以这是i的类型。添加U,它将看到一个unsigned int literal。否则,你想要像其他人建议的那样使用decltype,特别是因为sizeof(size_t)可能大于sizeof(int)(如果在64位长模式下运行,它在Windows,OS X等上)。
答案 3 :(得分:2)
讨论:
auto n = a.size();
for (auto i = n-n; i<n; ++i) {
}
请注意,对于小于int
的类型,减法结果会扩展为int
(称为整数提升)。
答案 4 :(得分:2)
尽可能尝试保持正确,我通常写道:
const auto n(a.size());
for (auto i = decltype(n){0}; i < n; ++i)
{
}
它并不简洁,但很明显,您希望将n
类型的变量初始化为0(n
为{{1 }})。
答案 5 :(得分:1)
这是一个简单的&amp;更清洁的解决方案,使其工作。
for(auto i: a)
{
}
答案 6 :(得分: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]
答案 7 :(得分:-2)
for(auto n = a.size(), i = 0; i != n; ++i) {
}
如果您需要访问索引以及实际元素,...可能是最干净的解决方案。
的更新强> 的
for(auto n = a.size(), i = n*0; i != n; ++i) {
}
理查德史密斯的评论是一种解决方法,虽然它看起来不再那么干净了。