自己的向量分配实现
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自己的向量分配实现相关的知识,希望对你有一定的参考价值。
我正在通过编写所有默认函数来实现类似于矢量的stl。还有一个问题,我不明白为什么它为简单类型调用ragn版本的assign,并且没有默认值。这是实现代码:Vector.h
void assign(size_t count, const T& value) // Default version
void assign(size_t count, const T& value)
if(this->_size < count)
this->allocator.deallocate(this->arr, this->_capacity);
this->arr = this->allocator.allocate(count);
this->_capacity = count;
for(size_t i = 0; i < count; ++i)
this->arr[i] = value;
this->_size = count;
template<class InputIt>
void assign(InputIt first, InputIt last) // Range version
size_t count = std::distance(first,last);
if(this->_size < count)
this->allocator.deallocate(this->arr, this->_capacity);
this->arr = this->allocator.allocate(count);
this->_capacity = count;
for(size_t i = 0; first != last; i++)
this->arr[i] = *first++;
this->_size = count;
主要代码:
Vector<int> vec;
vec.assign(5,10);
输出:
/MyVector/MyVector.h: In instantiation of ‘void Vector<T, Allocator>::assign(InputIt, InputIt) [with InputIt = int; T = int; Allocator = std::allocator]’:
../MyVector/main.cpp:52:24: required from here
../MyVector/MyVector.h:99:45: error: no matching function for call to ‘distance(int&, int&)’
size_t count = std::distance(first,last);
~~~~~~~~~~~~~^~~~~~~~~~~~
In file included from /usr/include/c++/7/bits/stl_algobase.h:66:0,
from /usr/include/c++/7/bits/char_traits.h:39,
from /usr/include/c++/7/ios:40,
from /usr/include/c++/7/ostream:38,
from /usr/include/c++/7/iostream:39,
from ../MyVector/main.cpp:1:
/usr/include/c++/7/bits/stl_iterator_base_funcs.h:138:5: note: candidate: template<class _InputIterator> constexpr typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator)
distance(_InputIterator __first, _InputIterator __last)
^~~~~~~~
/usr/include/c++/7/bits/stl_iterator_base_funcs.h:138:5: note: template argument deduction/substitution failed:
/usr/include/c++/7/bits/stl_iterator_base_funcs.h: In substitution of ‘template<class _InputIterator> constexpr typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator) [with _InputIterator = int]’:
../MyVector/MyVector.h:99:45: required from ‘void Vector<T, Allocator>::assign(InputIt, InputIt) [with InputIt = int; T = int; Allocator = std::allocator]’
../MyVector/main.cpp:52:24: required from here
/usr/include/c++/7/bits/stl_iterator_base_funcs.h:138:5: error: no type named ‘difference_type’ in ‘struct std::iterator_traits<int>’
In file included from ../MyVector/main.cpp:2:0:
../MyVector/MyVector.h: In instantiation of ‘void Vector<T, Allocator>::assign(InputIt, InputIt) [with InputIt = int; T = int; Allocator = std::allocator]’:
../MyVector/main.cpp:52:24: required from here
../MyVector/MyVector.h:107:36: error: invalid type argument of unary ‘*’ (have ‘int’)
this->arr[i] = *first++;
^~~~~~~~
Makefile:725: recipe for target 'main.o' failed
make: *** [main.o] Error 1
我正在使用C ++ 17
范围版本更适合vec.assign(5, 10);
与InputIt = int
。您应该以某种方式禁用不代表输入迭代器的模板参数的重载。
让我们来看看stdlibc++ implementation:
template<typename InputIt, typename = std::RequireInputIter<InputIt>>
void assign(InputIt first, InputIt last)
M_assign_dispatch(first, last);
其中RequireInputIter
is
template<typename InputIt>
using RequireInputIter = typename enable_if<is_convertible<typename
iterator_traits<InputIt>::iterator_category, input_iterator_tag>::value>::type;
换句话说,对于推导类型InputIt
,iterator_traits<InputIt>::iterator_category
类型应可转换为input_iterator_tag
。否则,由于assign
,将SFINAE重载从设置的重载分辨率中静默排除。
在C ++ 17中,可以使用RequireInputIter
和_t
助手来简化_v
:
template<typename InputIt>
using RequireInputIter = enable_if_t<is_convertible_v<typename
iterator_traits<InputIt>::iterator_category, input_iterator_tag>>;
还请注意,输入迭代器可用于遍历范围only once。调用std::distance(first, last)
后,除非InputIt
至少是一个正向迭代器,否则所有后续遍历该范围的尝试都是未定义的行为。对于输入迭代器,您无法确定要预分配多少空间。
这就是assign
在内部使用标签分发技术的原因。经过一些简化后,它看起来像这样:
template<typename InputIt, typename = std::RequireInputIter<InputIt>>
void assign(InputIt first, InputIt last)
M_assign_aux(first, last,
typename iterator_traits<InputIt>::iterator_category);
有两个M_assign_aux
重载
template<typename InputIt>
void M_assign_aux(InputIt first, InputIt last, std::input_iterator_tag);
template<typename ForwardIt>
void M_assign_aux(ForwardIt first, ForwardIt last, std::forward_iterator_tag);
做作业。第一个仅用于输入迭代器,第二个-用于正向迭代器以及从其派生的迭代器,即双向和随机访问迭代器。
您可以使用强制转换来调用特定的函数。喜欢:Assign((size_t)5,(const int&)10);
以上是关于自己的向量分配实现的主要内容,如果未能解决你的问题,请参考以下文章