模板成员函数写入输出迭代器

时间:2012-06-14 15:09:26

标签: c++ templates iterator virtual member-functions

我认为我会聪明并创建接受输出迭代器的成员函数。这样,我可以避免返回集合或通过引用获取集合。例如:

template <typename TOutIterator>
void getHeaderNames(TOutIterator destination);

template <typename TOutIterator>
void getHeaderValues(std::string const& name, TOutIterator destination);

这些函数会将结果写入传入的迭代器中。这样,我不必担心我是在写一个集合,向量还是ostream。

现在我感觉不那么聪明。我想将这些函数设置为虚拟,以便我可以在测试中删除实现。不幸的是,模板成员函数不能是虚拟的,这是有道理的。

有没有办法让这些函数保持通用(写入任何东西)并允许它们同时是虚拟的?我想避免将所有内容写入向量,只是为了转向并将其写入标准输出或其他任何内容。

如果我需要更清楚地解释我的情况,请告诉我。

3 个答案:

答案 0 :(得分:1)

您可以使用type erasure来操纵多态迭代器,例如any_iterator proposed by Thomas Becker(以及后来的implemented in Boost.Range)。你最终会得到一些东西:

typedef any_iterator<
  std::string, // Value
  Writable,    // Access
  Forward,     // Traversal
> StringOutputIterator; // can represent any output iterator accepting strings

virtual void getHeaders(StringOutputIterator destination);

类型擦除的想法是为一组其他不相关的类型(由于使用模板而在C ++中经常发生)具有公共基类。例如,std::function通过允许以类似的方式操作函数指针,仿函数或lambda来将此成语应用于可调用对象。

答案 1 :(得分:1)

我遇到了类似的问题,并且我不想将Boost添加到我的项目中...所以我决定根本不使用迭代器。

我最终使用了std::function

void getHeaderNames(std::function<void(std::string)> destination);

void getHeaderValues(std::string const& name, std::function<void(std::string)> destination);

然后,我提供一个执行std::back_inserter的lambda而不是push_back

std::vector<std::string> v;
getHeaderNames([&](auto name) { v.push_back(std::move(name)); });

答案 2 :(得分:0)

保持它们通用的一种方法,我通常在实践中看到这一点,是流输出操作符的两个重载(如果有意义)或者采用std::ostream&

当然这取决于你的确切情况:你在编写迭代器更有意义的算法吗?或者只想转储对象的内容?