【问题标题】:How do I write a function that can iterate over a generic type如何编写可以迭代泛型类型的函数
【发布时间】:2016-03-21 22:39:27
【问题描述】:

我想编写一个类似print_all 的函数,如下所述。

#include <iterator>
#include <vector>

template <typename V>
void print_all(std::iterator<std::input_iterator_tag, V> it) {
  for (; it != std::end(it); ++it) {
    V item = *it;
    // do stuff with item
  }
}

int main() {
  std::vector<int> myvec (10);

  print_all(myvec.cbegin());

  return 0;
}

我如何声明 print_all 以便它可以接受类型为 V 的任何迭代器?

编辑

我想以类型安全的方式执行此操作。一个更好的用例示例是累加器

#include <iterator>
#include <vector>
#include <functional>

template <typename V, typename K>
K accumulate(
      std::function<K(K, V)> accumulator,
      std::iterator<std::input_iterator_tag, V> it,
      std::iterator<std::input_iterator_tag, V> end,
      K initial) {
  K sum = initial;
  for (; it != end; ++it) {
    V item = *it;
    sum = accumulator(sum, item);
  }
  return sum;
}

现在你明白为什么这个问题不是this 的重复了。我觉得会有一种类型安全的方法来做到这一点,其中编译器确保迭代器迭代正确的类型。这就是为什么我不愿接受史蒂夫·洛里默的回答。

【问题讨论】:

  • std::end(it) 将不起作用 - 迭代器不知道他们正在迭代的容器 - 你需要传递结束迭代器,通过 std::end(myvec)myvec.end() 找到
  • 或者传递对容器本身的引用并在其上使用std::begin()std::end() 来获取迭代器。
  • 几乎是重复的,所以这里有很多不同的方法:stackoverflow.com/questions/10750057/…
  • 您应该将您的编辑移到一个单独的问题中。
  • 这是一个有趣的问题,@SteveLorimer。就我而言,您按照最初的措辞回答了这个问题,不幸的是,Sam 打算问一个完全不同的问题。

标签: c++ c++11 generics types


【解决方案1】:

假设您有所需的重载 std::ostream operators,您可以将实际的迭代器设为您的函数模板的类型

template<typename IterT>
void print_all(IterT begin, IterT end)
{
    while (begin != end)
        std::cout << *begin++ << ", ";
    std::cout << '\n';
}

如上所述,这仅在您具有必要的 std::ostream&amp; operator&lt;&lt;(...) 重载时才有效。

你可以这样称呼它:

int main()
{
    std::vector<int> myvec;

    // populate myvec...

    print_all(std::begin(myvec), std::end(myvec));
    return 0;
}

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-01-23
  • 1970-01-01
  • 2014-10-08
  • 1970-01-01
  • 1970-01-01
  • 2016-07-24
  • 2022-01-10
相关资源
最近更新 更多