【问题标题】:c++ how to copy range from vector using two iteratorsc++ 如何使用两个迭代器从向量中复制范围
【发布时间】:2010-12-30 16:21:01
【问题描述】:

我有这个无法编译的示例代码:

#include <iostream>
#include <vector>

using std::endl; using std::cin; using std::cout;
using std::vector;


int main()
{
    vector<int> vi, seg;
    vi.push_back(3);
    vi.push_back(4);
    vi.push_back(5);
    vi.push_back(6);
    vi.push_back(7);
    vector<int>::const_iterator ci_start = vi.begin();
    vector<int>::const_iterator ci_actual = vi.begin();
    while (ci_actual != vi.end())
    {   
        seg = vi(ci_start, ci_actual);
        cout << "......" ;
        for (const vector<int>::const_iterator ci = vi.begin();
                                    ci != vi.end(); ++ci)
            cout << *ci << " ";
        cout << endl;

        ++ci_actual;
    }   
}

我想要的是将向量vi 的增加部分(这将需要数百万个元素)传递给函数(未显示)。这些段从vi 的开头一直考虑到actual 目前所在的位置。
为此,我声明了应该是 vi 的一部分的 seg

期望的输出是:

3
3 4
3 4 5
3 4 5 6 3 4 5 6 7

seg 是否不应该包含由迭代器 ci_startci_actual 表示的 vi 元素的副本?

要将vi 的不断增加的部分传递给我引用的函数(不存在),我可以在不将vi 的元素复制到另一个向量的情况下更快地完成它,而只需传递对vi 段的引用?

【问题讨论】:

    标签: c++ vector iterator copy


    【解决方案1】:
    for (const vector<int>::const_iterator ci = vi.begin(); ci != vi.end(); ++ci)
    

    你在这里声明了一个 const const_interator。这意味着当您尝试调用 ++ci 时,编译器会因为您尝试修改常量变量而大喊大叫。这应该可以修复该编译器错误:

    for (vector<int>::const_iterator ci = vi.begin(); ci != vi.end(); ++ci)
    

    【讨论】:

    • 嗯,有两个错误,你解决了一个。谢谢你。但我仍然得到:ex.cpp:23: 错误:将 'const __gnu_cxx::__normal_iterator > >' 作为 '__gnu_cxx 的 'this' 参数传递::__normal_iterator<_iterator _container>& __gnu_cxx::__normal_iterator<_iterator _container>::operator++() [with _Iterator = const int*, _Container = std::vector >]'丢弃限定符
    • 这可能是由于@Lou 在下面指出的seg = vi(ci_start, ci_actual); 行。
    【解决方案2】:

    如果您有编译器错误,请告诉我们它是什么。它看起来像这样:

      seg = vi(ci_start, ci_actual);
    

    应该是

      vector<int> seg(ci_start, ci_actual);
    

    并删除 main() 顶部的 seg 声明。

    如果你想打印段,你的 for 循环应该使用 seg.begin()/seg.end()

    【讨论】:

    • 从 for 循环中的 vector 声明中删除 const 后,我再次尝试了您的建议,编译器不再抱怨。在 while 循环中继续重新声明 vector seg 似乎没有问题。变量不应该只声明一次吗?
    • 只声明一次。循环不会一直声明它——它会一直构造它,但这没关系,因为您希望每次迭代都有不同的 seg。
    【解决方案3】:

    Re:关于如何调用要在大向量的子范围上操作的辅助函数的后续问题...

    首先,this stackoverflow question 可能有用。接受的“只通过一对迭代器”的答案正是我要建议的。

    其次,如果您可以使用 boost 库,vector proxy libraries 可能会有用。

    【讨论】:

      【解决方案4】:
      int main()
      {
          vector<int> vi;
      
          vi.push_back(3);
          vi.push_back(4);
          vi.push_back(5);
          vi.push_back(6);
          vi.push_back(7);
      
          //the end of the sequence 
          vector<int>::iterator seq_end = vi.begin() + 1;
      
          while (seq_end != vi.end())
          {
              cout << "......" ;
              for (vector<int>::iterator ci = vi.begin(); ci != seq_end; ++ci)
                  cout << *ci << " ";
              cout << endl;
      
              any_function(vi.begin(), seq_end);
      
              ++seq_end;
          }   
      }
      
      void any_function(const vector<int>::iterator& seq_start,
                        const vector<int>::iterator& seq_end)
      {
          ...
      }
      

      此代码可以生成、分析和修复您的错误。

      【讨论】:

      • 嗨,我问的不是这个。假设向量vi 有1000 万个元素。如上所述,在 while 循环的每次迭代中,我想将来自 vi 的元素作为参数传递。在第一次迭代中:1 个元素;在 2nd 中,两个元素(1st e 2nd),依此类推。我的问题是:我真的需要为此创建向量段吗?如果是这样,我需要在每次迭代中将元素从vi 复制到seg,这很昂贵。或者我可以将指针传递给vi 以避免复制吗?还是其他解决方案?
      • 那么你不需要 seg,只需将 vi 作为 const 引用发送
      猜你喜欢
      • 1970-01-01
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      • 2016-05-08
      • 2022-01-20
      • 2021-05-27
      • 2020-01-28
      • 1970-01-01
      相关资源
      最近更新 更多