【问题标题】:Iterate Multiple std::vector迭代多个 std::vector
【发布时间】:2011-01-13 02:51:51
【问题描述】:

我在这里和其他地方读过,在使用索引迭代 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&lt;int&gt;::size_type

属于同一类型
std::vector<double>::size_type

只使用 std::size_t 是否安全?

谢谢。

【问题讨论】:

  • 如果你被教导过这样的迭代,那么你被教导错了。除了 i++ 任何体面的编译器都应该优化为 ++i 之外,您仍然在循环的每一轮调用 x.size(),如果它不平凡且不是内联是浪费的。
  • @Matthieu,只是一个快速而肮脏的例子来说明我的问题。我也应该使用迭代器而不是按索引来做。

标签: c++ stl iterator


【解决方案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 进行迭代

【讨论】:

  • 为什么不在控制体中增加j?而且您也因不使用maxend 变量来检查迭代的结束而受苦...坚持for_each 真的;)
  • @MatthieuM,当您需要遍历两个不同的向量时,如何使用 foreach?显然这个例子是陈腐的,循环可以分开,我想不出一种方法来为 x[i] = y[i] + 3
【解决方案2】:

我认为您可以放心地假设size_type 是一个无符号的非负整数。除此之外,你不能依赖太多。当然,大多数容器都有一个size_type,它与size_t 相同,但不能保证。

SGI 文档和此来源http://www.cplusplus.com/reference/stl/vector/ 似乎同意这一点。

您可能还想看看这个解决方案来解决您的问题:http://rosettacode.org/wiki/Loop_over_multiple_arrays_simultaneously#C.2B.2B

我希望这会有所帮助。

【讨论】:

    【解决方案3】:

    嗯,我认为:

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

    这是一个完美的委员会——你期望你的向量真的很大吗?就个人而言,我使用unsigned int,零问题。

    现在我想反对票将开始......

    【讨论】:

    • @Neil,喜欢“完美委员会”。我使用的是 unsigned int 但读到这样的东西:stackoverflow.com/questions/409348/iteration-over-vector-in-c,让我们担心。可能是不必要的担心。
    • @Neil:你永远活不了那么久——我猜没有人愿意被指责为完美主义者:-D
    • @Mark 如果您使用的是无符号类型,那么您可以,恕我直言。 litb 对您链接的问题的回答(当然)是正确的,但您真的必须喜欢打字(在两种意义上)才能使用 size_type。
    【解决方案4】:

    是的,对于几乎任何实际目的,您都可以使用 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));
    

    【讨论】:

      【解决方案5】:

      一般来说,C++ 标准不提供这样的保证:不同参数化容器的 size_types 不相等,size_t 也不相等。

      【讨论】:

      • +1。你是对的,std::size_t 保证仅适用于分配器。我认为std::vector::size_type 必须等于Allocator::size_type,但显然不是。
      • @avakar:情况是标准分配器使用 size_t 作为其 size_type,并且所有已知的标准容器实现都从其关联的分配器传递 size_type。因此,除非您编写自己的分配器,否则它将是 size_t。从实际的角度来看, size_t 基本上总是可以工作,无论他们使用什么作为 size_type - 例如::operator new 使用 size_t 作为分配的大小,基本上所有其他分配都通过它(至少默认情况下)。
      猜你喜欢
      • 1970-01-01
      • 2012-05-07
      • 1970-01-01
      • 2017-02-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多