【问题标题】:Iterate over range with given first and last iterator使用给定的第一个和最后一个迭代器迭代范围
【发布时间】:2012-11-09 19:12:32
【问题描述】:

我得到了这样一段代码:

template<class Iter>
void printRange(Iter begin, Iter last) {
    for (Iter i = begin; i != last; i++) {
        std::cout << *i << ", ";
    }
     outstd::cout << *last << ", ";
}

我的问题是:我怎样才能优雅地打印出最后一个元素?在循环之后单独计算最后一个元素似乎不是一个很好且正确的解决方案,......有更好的方法吗?请注意,我也不能使用

【问题讨论】:

  • 通常,“last”迭代器确实指向 past 最后一个元素,因此您的代码可以正常工作并打印出每个元素。你确定last 也指向一个有效的元素吗?
  • 是的,实际上这不是我的代码,我只是尝试使用/修改它。如果是过去的最后一个,无论如何我都会称它为end
  • @jalf,当你用“find”找到你的两个迭代器并且你想用它们打印它们之间的所有迭代器时,我遇到了同样的问题。
  • 这是一个糟糕的功能,有两个原因。一,它的名字没有意义,因为它不打印容器,它打印范围。第二,它不遵循接受半开范围的公认和受人尊敬的传统。那么,你为什么要使用它呢?
  • 因为这一系列函数使用数组,并且像printRange(testArray, testArray + n-1) 一样被调用。对不起,如果名字有误导性,我匆忙编辑了它。其次,这不是我的代码。 :)

标签: c++ iterator containers


【解决方案1】:

在 STL 中,最后一个迭代器不包含值,因此您的循环在这种情况下可以工作。

也许您应该考虑在列表末尾添加另一个不包含任何值的迭代器,这样您就可以与 STL 保持一致。

【讨论】:

    【解决方案2】:

    对于 STL 容器类,迭代器值 end 在最后一项之后。一旦 end 到达,它可以退出,因为所有项目都已处理完毕。

    【讨论】:

      【解决方案3】:

      你可以这样做:

      template<class Iter>
      void printContainer(Iter begin, Iter last) {
          Iter afterEnd = end;
          afterEnd++;
          for (Iter i = begin; i != afterEnd; i++) {
              std::cout << *i << ", ";
          }
           outstd::cout << *last << ", ";
      }
      

      但请注意,如果 end 由 STL 库(如 list.end())提供,则它已经是最后一个元素之后的值,++ 将引发异常。

      所以我会以你拥有的方式使用你拥有的代码。但是当我调用它时,我将它传递给我要打印的最后一个值之后的值。

      【讨论】:

        【解决方案4】:

        可以有条件地输出分隔符:

        template<class Iter>
        void printContainer(Iter first, Iter last) {
            for (Iter i = first, end = ++last; i != end; i++) {
                std::cout << (i == first ? "" : ", ") << *i;
            }
        }
        

        对于更标准的[begin, end) 半开范围:

        template<class Iter>
        void printContainer(Iter begin, Iter end) {
            for (Iter i = begin; i != end; i++) {
                std::cout << (i == begin ? "" : ", ") << *i;
            }
        }
        

        【讨论】:

        • 正如我在我的 OP 中已经说过的,这是用真正的 last 元素调用的,而不是 end。但这将是更好的解决方案,我同意。
        • @WonderCsabo 啊,好的。我已经添加了两种解决方案。
        猜你喜欢
        • 2019-04-26
        • 2012-10-23
        • 2019-12-07
        • 2023-03-17
        • 1970-01-01
        • 2013-12-04
        • 2018-09-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多