C++ std::vector-like容器的高效实现&x27;s构造函数

C++ std::vector-like容器的高效实现&x27;s构造函数,c++,constructor,stdvector,implementation,C++,Constructor,Stdvector,Implementation,std::vector有一个构造函数,其形式为 template< class InputIt > vector( InputIt first, InputIt last, const Allocator& alloc = Allocator() ); template 向量(先输入,后输入, 常量分配器&alloc=Allocator()); 那么,如果迭代器不是随机访问迭代器,如何实现该构造函数呢? 我想出了两个候选人 在循环中,调用push_back

std::vector
有一个构造函数,其形式为

template< class InputIt >
vector( InputIt first, InputIt last,
        const Allocator& alloc = Allocator() );
template
向量(先输入,后输入,
常量分配器&alloc=Allocator());
那么,如果迭代器不是随机访问迭代器,如何实现该构造函数呢?
我想出了两个候选人

  • 在循环中,调用
    push_back(*first)
    (假设push_back已经实现),而first!=最后
  • 通过
    std::distance(first,last)

    计算元素的数量 然后分配足够的内存,然后复制所有元素
  • 哪一个更好?或者你还有其他想法吗

    添加:

    糟糕的是,如果迭代器是一个输入迭代器,那么想法2甚至不可能实现。

    通常的实现类似

    private:
    template<class input_iterator>
    std::size_t size_if_possible(input_iterator first, input_iterator last, std::input_iterator_tag) {
    }
    template<class input_iterator>
    std::size_t size_if_possible(input_iterator first, input_iterator last, std::forward_iterator_tag) {
        return std::distance(first, last);
    }
    
    public:
    template<class input_iterator>
    vector(input_iterator first, input_iterator last) {
        reserve(size_if_possible(first, last, std::iterator_traits<input_iterator>::tag{}));
        while (first != last) {
            emplace_back(*first);
            first++;
        }
    }
    
    private:
    模板
    std::size\u t size\u如果可能(首先输入迭代器,最后输入迭代器,std::input迭代器标记){
    }
    模板
    std::size\u t size\u如果可能(首先输入迭代器,最后输入迭代器,std::forward迭代器标记){
    返回标准::距离(第一个、最后一个);
    }
    公众:
    模板
    向量(先输入迭代器,后输入迭代器){
    保留(如果可能的话,大小(第一,最后,std::iterator_traits::tag{}));
    while(第一个!=最后一个){
    向后安置(*第一);
    第一++;
    }
    }
    

    这允许它在传入前向迭代器时保留,在传入单次传入输入迭代器时有效地跳过保留,让您两全其美。

    如果传入前向迭代器,它将使用距离+保留。否则就不行了。@MooingDuck,谢谢。但是你能解释一下原因吗?谢谢,但是,问题是,如果迭代器是前向迭代器而不是随机访问迭代器,那么这种实现会在该范围内迭代两次。这种迭代器的迭代速度通常很慢。因此,本质上,这个问题是询问冗余和缓慢迭代与潜在重新分配的成本。没有考虑,答案就没有意义了。