也许这个问题很简单,但第二次考虑这个问题我想知道如何以正确的方式做到以下几点:
std::vector<K> v = ...;
for(T i=0; i<v.size(); ++i) {
const K& t = v[i];
// use t *and i*
}
T
应该是什么类型的? int
,unsigned int
,int32_t
,size_t
(v.size()
的类型)或任何其他建议?请尝试考虑可移植性,错误倾向和性能,并在答案中保持客观。
编辑:我没有选择迭代器,因为它也想明确地使用索引号。
答案 0 :(得分:6)
i
的类型应与size()
的返回值相同,即std::vector<K>::size_type
。但是,在实践中,size_t
会做得很好。如果您使用 signed 整数类型,那么您的编译器可能会在小于比较中警告有符号/无符号的不匹配。
通常你会为此使用迭代器:
std::vector<K> v = ...;
for (std::vector<K>::iterator i = v.begin(); i != v.end(); ++i) {
const K& t = *i;
// use t
}
或者,在C ++ 0x中:
std::vector<K> v = ...;
for (auto i = v.begin(); i != v.end(); ++i) {
const K& t = *i;
// use t
}
在回答您关于将迭代器使用向量索引的注释时,请考虑std::distance()
函数,它是向量迭代器的常量时间操作:
std::vector<K> v = ...;
for (auto i = v.begin(); i != v.end(); ++i) {
const K& t = *i;
size_t index = std::distance(v.begin(), i);
// use t and index
}
答案 1 :(得分:3)
v.size
返回的类型v[]
预期的类型为std::vector<K>::size_type
。
但是,请考虑使用迭代器:超出界限的风险较低,您可以使用标准库算法。
答案 2 :(得分:3)
类型T通常无关紧要,只要它与矢量大小一样大。
在表现方面,不应有任何差异。
在易错性/可移植性方面,我建议使用有符号整数,因为如果你以某种方式从i
中减去值,你会得到一个很大的正数,这就更难了检查比负数。但是因为v.size()
是size_t
,如果对T使用有符号整数,v
≥2 31 (或2 63 )项目,i
必须在结束前变为无效。但我认为如果向量需要非常大(特别是在64位平台上),那么还有一个比选择类型T更大的问题。
切勿将int32_t
用于计数器。
(这些是在OP的编辑之前:)
但是在你的情况下,你可能希望用迭代器迭代。
for (std::vector<K>::const_iterator cit = v.begin(); cit != v.end(); ++ cit) {
const K& t = *cit;
// ...
}
使用Boost.Foreach你可以把这个烂摊子变成
BOOST_FOREACH(const K& t, v) {
// ...
}
在C ++ 0x中,这变为built-in feature(§[stmt.ranged]),但AFAIK还没有编译器支持它:
for (const K& t : v) {
// ...
}
但是大多数声称支持C ++ 0x的编译器应该允许auto
:
for (auto cit = v.cbegin(); cit != v.cend(); ++ cit) {
const K& t = *cit;
// ...
}
或lambda表达式:
std::for_each(v.cbegin(), v.cend(), [](const K& t) {
...
});