迭代器和模板 [英] Iterators and templates
问题描述
我正在尝试实现一个允许用户输入某种类型的开始和结束迭代器的函数,然后所有函数都对数据执行一些操作。但是,该函数必须足够通用,它应该适用于许多类型的迭代器(例如 std :: vector :: iterator
, std :: string :: iterator
, std :: iterator
等)。唯一的限制是迭代器必须至少 forward_iterator_tag
功能。
I'm trying to implement a function which allows the user to input some type of begin and end iterator, then all perform some operation on the data. However, the function has to be generic enough it should work for many types of iterators (for example std::vector::iterator
, std::string::iterator
, std::iterator
, etc.). The only limit is that the iterators have to be at least forward_iterator_tag
capabilities.
我的函数原型如下所示:
My function prototype looks like this:
template <class key_type, class data_type> std::shared_ptr<data_type>
remove(std::iterator<std::forward_iterator_tag, key_type> key_start,
std::iterator<std::forward_iterator_tag, key_type> key_end);
然而,这限制我专门使用 forward_iterator_tag
迭代器,所以试图像这样调用函数:
However, this limits me to using specifically a forward_iterator_tag
iterator, so trying to call the function like this:
remove<char, char>(std::iterator<std::random_access_iterator_tag, char>(), std::iterator<std::random_access_iterator_tag, char());
将失败,因为编译器无法转换 std :: iterator< std :: random_access_iterator_tag,...>
到 std :: iterator< std :: forward_access_iterator_tag,...>
。此外,此方法不适用于字符串迭代器,向量迭代器或其他stl迭代器。
will fail because the compiler can't convert a std::iterator<std::random_access_iterator_tag,...>
to a std::iterator<std::forward_access_iterator_tag,...>
. Additionally, this method does not work for string iterators, vector iterators, or other stl iterators.
有人知道stl如何实现容器/字符串以接受每个迭代器的迭代器其他?例如,这正确编译:
Does someone know how the stl implements the containers/strings to accept iterators from each other? For example, this compiles correctly:
std::string a = "hello";
std::vector<char> v(a.begin(), a.end());
推荐答案
template < typename Iter >
void fun_impl(Iter begin, Iter end, std::forward_iterator_tag)
{
// do your stuff here...
}
template < typename Iter >
void fun(Iter begin, Iter end)
{
fun_impl(begin,end, std::iterator_traits<Iter>::iterator_category());
}
返回的类型begin()$各种容器的c $ c>和
end()
的类型不是 iterator< category ...>
但是这种(有时)的子类。在编写通用代码时,您永远不会以特定的迭代器类型为目标。相反,您使用标签分派来对迭代器进行分类并调用正确的实现。由于random_iterator_tag是一个forward_iterator_tag,它会自动转换为这样,以便上面的 fun_impl
可以正确解析任何forward_iterator或扩展名。
The types returned by begin()
and end()
for various containers are not of type iterator<category...>
but subclasses of such (sometimes). You never, when you're writing generic code, target a specific iterator type. Instead you use "tag dispatching" to classify the iterator and call the correct implementation. Since random_iterator_tag is-a forward_iterator_tag it will be automatically converted to such so that the above fun_impl
will resolve correctly for any forward_iterator or extension.
这篇关于迭代器和模板的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!