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,谢谢。但是你能解释一下原因吗?谢谢,但是,问题是,如果迭代器是前向迭代器而不是随机访问迭代器,那么这种实现会在该范围内迭代两次。这种迭代器的迭代速度通常很慢。因此,本质上,这个问题是询问冗余和缓慢迭代与潜在重新分配的成本。没有考虑,答案就没有意义了。