【问题标题】:C++ generic iteratorC++ 泛型迭代器
【发布时间】:2014-12-30 21:18:09
【问题描述】:

我不确定我能找到的答案是否是满足我需要的最简单方法。我知道如何修改为我的问题的完整解决方案的简单模板将是完成以下操作的代码:

  1. 将两个迭代器作为输入,指向包含值类型 T 的事物的可迭代容器(向量、列表...)的开头和结尾。

  2. 返回一个std::vector<T>,其中包含输入容器的逐个元素副本,按从头到尾迭代输入容器所完成的任何顺序。

一些不起作用的东西如下:

 template<typename Iterator, typename T>
 std::vector<T> dumb_copy(Iterator first, Iterator last) { ... }

问题是我需要编译器以某种方式检查我是否获得了指向 T 类型的迭代器。

我目前正在学习 C++,并在实践中编写我能想到的某些算法的最通用实现,因此我想从一开始就获得最佳实践。如果有一种使用 C++11 结构的简单方法可以做到这一点,那对我来说很好。

【问题讨论】:

  • 为什么需要这个?你不能只从两个迭代器构造向量吗? BTW 标准库迭代器定义value_type,它给你T
  • 我认为我需要这个,因为我还没有深入到 Stroustrup...

标签: c++ generics iterator


【解决方案1】:

您可以简单地使用特征来完全删除 T 类型,使其自动确定:

template <typename Iterator>
std::vector<typename std::iterator_traits<Iterator>::value_type>
    dumb_copy(Iterator first, Iterator last)
{
    std::vector<typename std::iterator_traits<Iterator>::value_type> copy;

    // Populate the copy vector

    return copy;
}

特别注意std::iterator_traits 在迭代器类型是指针时有一个特化,因此这将允许您的函数“正常工作”,即使它传递的是指针而不是“真正的”迭代器对象。

【讨论】:

    【解决方案2】:

    您不需要这样做,因为标准库容器已经以这种方式工作。所以你可以直接从两个迭代器创建一个std::vector

    #include <string>
    #include <vector>
    #include <iostream>
    
    int main()
    {
        std::string s = "hello"; // iterable container
    
        // construct a vector using two iterators
        std::vector<std::string::value_type> v(s.begin(), s.end());
    
        // check the results
        for(unsigned i = 0; i < v.size(); ++i)
            std::cout << v[i];
        std::cout << '\n';
    }
    

    【讨论】:

    • 谢谢。正如我所说,模板的重点只是让类型正确。我感兴趣的是实现一种算法,该算法将依次遍历输入容器、一些非平凡的处理,并将解决方案存储到向量中。
    • @JT1 那么听起来你可能会从std::for_each()中受益:cplusplus.com/reference/algorithm/for_each
    【解决方案3】:

    您可以为其中一个迭代器创建一个类型与*it 的结果匹配的std::vector&lt;T&gt;

    #include <type_traits>
    #include <vector>
    template <typename Iterator>
    auto dump_copy(Iterator begin, Iterator end)
        -> std::vector<typename std::decay<decltype(*begin)>::type> {
        return std::vector<typename std::decay<decltype(*begin)>::type(begin, end);
    }
    

    使用 C++14,您可以将 typename std::decay&lt;X&gt;::type 替换为 std::decay_t&lt;X&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-05
      • 2012-02-27
      • 1970-01-01
      • 1970-01-01
      • 2010-12-06
      • 1970-01-01
      • 2018-12-09
      • 2019-07-19
      相关资源
      最近更新 更多