[英]Template Member Function to Write to Output Iterator
I thought I would be smart and create member functions that accepted output iterators. 我以为我会聪明并创建接受输出迭代器的成员函数。 This way, I could avoid returning a collection or taking a collection by reference.
这样,我可以避免返回集合或通过引用获取集合。 For example:
例如:
template <typename TOutIterator>
void getHeaderNames(TOutIterator destination);
template <typename TOutIterator>
void getHeaderValues(std::string const& name, TOutIterator destination);
These functions will write their results to whatever iterator is passed in. This way, I don't have to worry whether I'm writing to a set, vector or ostream. 这些函数会将结果写入传入的迭代器中。这样,我不必担心我是在写一个集合,向量还是ostream。
Now I don't feel so smart. 现在我感觉不那么聪明。 I want to make these functions virtual so I can stub out the implementation in test.
我想将这些函数设置为虚拟,以便我可以在测试中删除实现。 Unfortunately, template member functions can't be virtual, which makes sense.
不幸的是,模板成员函数不能是虚拟的,这是有道理的。
Is there a way to keep these functions generic (write to anything) and allow them to be virtual at the same time? 有没有办法保持这些函数通用(写入任何东西)并允许它们同时是虚拟的? I want to avoid writing everything to a vector only to turn around and write it to standard out or whatever.
我想避免将所有内容写入向量,只是转向并将其写入标准输出或其他任何内容。
Let me know if I need to explain my situation more clearly. 如果我需要更清楚地解释我的情况,请告诉我。
You could use type erasure to manipulate polymorphic iterators, like the any_iterator
proposed by Thomas Becker (and later implemented in Boost.Range ). 您可以使用类型擦除来操作多态迭代器,例如Thomas Becker提出的
any_iterator
(后来在Boost.Range中实现 )。 You would end up with something along those lines: 你最终会得到一些东西:
typedef any_iterator<
std::string, // Value
Writable, // Access
Forward, // Traversal
> StringOutputIterator; // can represent any output iterator accepting strings
virtual void getHeaders(StringOutputIterator destination);
The idea of type erasure is to have a common base class for a set of otherwise unrelated types (which happen very often in C++, due to the use of templates). 类型擦除的想法是为一组其他不相关的类型(由于使用模板而在C ++中经常发生)具有公共基类。 For instance,
std::function
applies this idiom to callable objects, by allowing the manipulation of function pointers, functors or lambdas in a similar way. 例如,
std::function
通过允许以类似方式操作函数指针,仿函数或lambda来将此成语应用于可调用对象。
I faced a similar problem, and I didn't want to add Boost to my project... so I decided not to use iterators at all. 我遇到了类似的问题,我不想将Boost添加到我的项目中......所以我决定不使用迭代器。
I ended up using a std::function
instead: 我最终使用
std::function
代替:
void getHeaderNames(std::function<void(std::string)> destination);
void getHeaderValues(std::string const& name, std::function<void(std::string)> destination);
Then, instead of std::back_inserter
, I provide a lambda that executes push_back
: 然后,我提供了一个执行
push_back
的lambda,而不是std::back_inserter
:
std::vector<std::string> v;
getHeaderNames([&](auto name) { v.push_back(std::move(name)); });
One way to keep them generic, and I usually see this in practice, is two overload a stream output operator (if it makes sense) or take an std::ostream&
. 保持它们通用的一种方法,我通常在实践中看到这是两个重载流输出操作符(如果它有意义)或采取
std::ostream&
。
Of course it depends on your exact situation: Are you writing an algorithm for which iterators make more sense? 当然这取决于你的确切情况:你在编写迭代器更有意义的算法吗? Or just want to dump an object's content?
或者只想转储对象的内容?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.