迭代多个std::vector

11

我在这里和其他地方阅读到,当使用索引迭代std::vector时应该:

std::vector <int> x(20,1);
for (std::vector<int>::size_type i = 0; i < x.size(); i++){
  x[i]+=3;
}

但是如果您要迭代两个不同类型的向量呢:

std::vector <int> x(20,1);
std::vector <double> y(20,1.0);
for (std::vector<int>::size_type i = 0; i < x.size(); i++){
  x[i]+=3;
  y[i]+=3.0;
}

可以安全地假设

std::vector<int>::size_type

与相同类型

std::vector<double>::size_type

仅使用 std::size_t 安全吗?


如果你被教授了这样的迭代方式,那么你被教错了。除了任何一个好的编译器都应该优化为 ++ii++ 之外,你仍然在每次循环时调用 x.size(),如果它不是微不足道的并且不是内联的话,这是浪费的。 - Matthieu M.
@Matthieu,这只是一个简单而粗糙的示例,以说明我的问题。我应该使用迭代器而不是通过索引来实现。 - Mark
如果你很谨慎,你可以使用 std::common_type<...::size_type, ...::size_type>,https://en.cppreference.com/w/cpp/types/common_type - alfC
5个回答

8

对于几乎所有实际目的,您可以使用std::size_t。虽然有一个意图,即不同的容器可以使用不同的大小类型,但基本上可以保证(至少对于标准容器),size_type与size_t相同。

或者,您可以考虑使用算法,例如:

std::transform(x.begin(), x.end(), x.begin(), std::bind2nd(std::plus<int>(), 3));
std::transform(y.begin(), y.end(), y.begin(), std::bind2nd(std::plus<double>(), 3.0));

2
一般来说,C++标准不会保证不同参数化容器的size_types相等,也不保证它们与size_t相等。

+1。而且你是正确的,std::size_t 的保证只适用于分配器。我原以为 std::vector::size_type 必须等于 Allocator::size_type,但显然不是这样。 - avakar
@avakar:情况是标准分配器使用size_t作为其size_type,所有已知的标准容器实现都从它们关联的分配器中传递size_type。因此,除非您编写自己的分配器,否则它将是size_t。从实际角度来看,无论他们使用什么作为size_type,size_t基本上总是有效的--例如,::operator new使用size_t作为分配大小,而基本上所有其他分配都通过它进行(至少默认情况下)。 - Jerry Coffin

2

1

嗯,我认为:

 for (std::vector<int>::size_type i = 0; i < x.size(); i++){

这有点完美主义 - 你期望你的向量非常巨大吗?个人而言,我使用unsigned int,毫无问题。

现在,我想开始负投票了...


@Neil,喜欢“完美委员会”。我一直在使用无符号整数,但是阅读像这样的内容:https://dev59.com/SHRC5IYBdhLWcg3wG9Nb,让我有些担心。可能是不必要的担心。 - Mark
@Neil:你永远也活不到那个时候——我猜没有人想被指责为完美主义者吧 :-D - Alexander Poluektov
2
@Mark 如果你使用的是无符号类型,我认为你没问题。litb对你链接的问题的回答是(当然)正确的,但你真的必须喜欢打字(在两个意义上)才能使用size_type。 - anon

-1

你应该使用迭代器

std::vector <int> x(20,1);
std::vector <double> y(20,1.0);
std::vector<double>::iterator j = y.begin();
for (std::vector<int>::iterator i = x.begin(); i != x.end(); ++i){
  *i +=3;
  *j +=3.0;
  ++j;
}

因为不能保证u size_type是相同的内部类型,无论如何,对于std::vector,您可以使用unsigned int进行迭代。


1
为什么不在for循环体中递增“j”?而且你也会因为没有使用“max”或“end”变量来检查迭代的结束而遭受苦难...坚持使用“for_each”吧 ;) - Matthieu M.
@MatthieuM,当你需要迭代两个不同的向量时,你如何使用foreach?显然,这个例子是陈词滥调的,循环可以分开,但我想不出如何为x[i] = y[i] + 3做到这一点。 - Jamie Cook

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接