【问题标题】:Iterators and templates迭代器和模板
【发布时间】:2011-07-01 19:33:35
【问题描述】:

我正在尝试实现一个功能,该功能允许用户输入某种类型的开始和结束迭代器,然后对数据执行一些操作。但是,该函数必须足够通用,它应该适用于多种类型的迭代器(例如std::vector::iteratorstd::string::iteratorstd::iterator 等)。唯一的限制是迭代器必须至少具有forward_iterator_tag 能力。

我的函数原型是这样的:

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 迭代器,因此尝试像这样调用函数:

remove<char, char>(std::iterator<std::random_access_iterator_tag, char>(), std::iterator<std::random_access_iterator_tag, char());

将失败,因为编译器无法将 std::iterator&lt;std::random_access_iterator_tag,...&gt; 转换为 std::iterator&lt;std::forward_access_iterator_tag,...&gt;。此外,此方法不适用于字符串迭代器、向量迭代器或其他 stl 迭代器。

有人知道 stl 如何实现容器/字符串来接受彼此的迭代器吗?例如,这编译正确:

std::string a = "hello";
std::vector<char> v(a.begin(), a.end());

【问题讨论】:

    标签: c++ templates stl iterator


    【解决方案1】:
    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()end() 为各种容器返回的类型不是iterator&lt;category...&gt; 类型,而是此类(有时)的子类。当您编写通用代码时,您永远不会针对特定的迭代器类型。相反,您使用“标签调度”对迭代器进行分类并调用正确的实现。由于 random_iterator_tag 是一个 forward_iterator_tag ,它会自动转换成这样,这样上面的 fun_impl 就可以正确解析任何 forward_iterator 或扩展。

    【讨论】:

    • +1。实际上,上面的代码在例如时有效。 Iter是一个T*,显然没有继承std::iterator
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-09
    • 2013-04-29
    • 2016-02-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多