迭代std :: vector(没有迭代器)时使用哪种类型?

时间:2010-07-27 09:14:00

标签: c++

也许这个问题很简单,但第二次考虑这个问题我想知道如何以正确的方式做到以下几点:

std::vector<K> v = ...;
for(T i=0; i<v.size(); ++i) {
  const K& t = v[i];
  // use t *and i*
}

T应该是什么类型的? intunsigned intint32_tsize_tv.size()的类型)或任何其他建议?请尝试考虑可移植性,错误倾向和性能,并在答案中保持客观。

编辑:我没有选择迭代器,因为它也想明确地使用索引号。

3 个答案:

答案 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) { 
   ...
});