C++ 要写入输出迭代器的模板成员函数
我认为我会很聪明,创建接受输出迭代器的成员函数。这样,我就可以避免返回集合或引用集合。例如:C++ 要写入输出迭代器的模板成员函数,c++,templates,iterator,virtual,member-functions,C++,Templates,Iterator,Virtual,Member Functions,我认为我会很聪明,创建接受输出迭代器的成员函数。这样,我就可以避免返回集合或引用集合。例如: template <typename TOutIterator> void getHeaderNames(TOutIterator destination); template <typename TOutIterator> void getHeaderValues(std::string const& name, TOutIterator destination);
template <typename TOutIterator>
void getHeaderNames(TOutIterator destination);
template <typename TOutIterator>
void getHeaderValues(std::string const& name, TOutIterator destination);
模板
作废总部地址(目的地);
模板
void getHeaderValues(std::string const&name,totiterator destination);
这些函数将把结果写入传入的任何迭代器。这样,我就不必担心是向集合、向量还是ostream写入
现在我觉得自己不那么聪明了。我想使这些函数成为虚拟的,这样我就可以在测试中删除实现。不幸的是,模板成员函数不能是虚拟的,这是有道理的
有没有一种方法可以使这些函数保持通用性(写入任何内容),同时允许它们是虚拟的?我希望避免将所有内容都写入向量,而只是将其转过来写入标准输出或其他任何内容
如果需要更清楚地解释我的情况,请告诉我。您可以使用来操作多态迭代器,如(及更高版本)。你最终会得到这样的结果:
typedef any_iterator<
std::string, // Value
Writable, // Access
Forward, // Traversal
> StringOutputIterator; // can represent any output iterator accepting strings
virtual void getHeaders(StringOutputIterator destination);
typedef任意迭代器<
std::string,//值
可写,//访问
向前,//遍历
>StringOutputIterator;//可以表示任何接受字符串的输出迭代器
虚拟void getHeaders(StringOutputIterator目标);
类型擦除的思想是对一组不相关的类型有一个共同的基类(由于使用模板,这在C++中经常发生)。例如,
std::function
通过允许以类似的方式操纵函数指针、functor或lambda,将此习惯用法应用于可调用对象。保持它们通用性的一种方法,我通常在实践中看到,是两个重载流输出操作符(如果有意义的话)或采用std::ostream&
当然,这取决于您的具体情况:您是否正在编写一个迭代器更有意义的算法?或者只是想转储一个对象的内容?我遇到了类似的问题,我不想给我的项目添加Boost。。。所以我决定根本不使用迭代器 我最终使用了
std::function
:
void getHeaderNames(std::function<void(std::string)> destination);
void getHeaderValues(std::string const& name, std::function<void(std::string)> destination);
在我的对象内部,有一个映射,表示从HTTP请求返回的头键/值对。我想允许在不暴露底层数据结构的情况下对键和每个键的值进行迭代(例如,一个多重映射也可以工作)。Boost中是否有任何迭代器所在的特定头?@TravisParks:检查答案中的链接。但是,Boost.Range中的
any\u迭代器
被用作any\u Range
的实现细节,我不确定它是否是供库用户使用的。您可以尝试使用它,或者提出自己的版本(从Becker和Grove的实现中获得灵感)。我还有另一个想法:我可以创建一个具有begin/end方法的header集合类。这些方法仍然需要返回一个没有公开实现细节的迭代器类型。任何迭代器都不会是间接的。
std::vector<std::string> v;
getHeaderNames([&](auto name) { v.push_back(std::move(name)); });