如何使构造函数接受所有类型的迭代器? [英] How to make constructor accept all type of iterators?
问题描述
我正在创建一个自定义的Vector/ArrayList类.但是我在创建构造函数的迭代版本时遇到了麻烦.下面的代码有效,但是问题是当我想要创建这样的ArrayList时:
I am creating a custom Vector/ArrayList class. But i´m having troubles creating the iterative version of the constructor. The following code works, but the problem is when i want to create ArrayList like this:
ArrayList arr(1, 5);
编译器不知道应该选择哪个版本的函数.
The compiler doesn't know what version of the function should pick.
我该如何解决?
构造函数:
ArrayList(const size_type elem_amount, value_type elem) : arr_size { elem_amount }, arr_capacity{ elem_amount }
{
array = std::uninitialized_fill_n(allocator.allocate(arr_size), arr_size, elem) - arr_size;
first = array;
last = array + arr_size - 1;
}
template<typename ITER>
ArrayList(ITER begin, ITER end) : arr_size{ static_cast<size_type>(end - begin) }, arr_capacity{ arr_size }
{
std::uninitialized_copy(begin, end, array = allocator.allocate(arr_size));
first = array;
last = array + arr_size - 1;
}
推荐答案
您需要做的是使用 std::iterator_traits
的iterator_category
进行检查给你
What you need to do is use SFINAE to constrain the template to only work when the template type is deduced to be an iterator type. Since you do arr_size{ static_cast<size_type>(end - begin) }
to initialize size
this means that you expect the iterators to be random access. We can check for that using the iterator_category
of std::iterator_traits
Doing that gives you
template<typename ITER,
std::enable_if_t<std::is_base_of_v<typename std::iterator_traits<ITER>::iterator_category,
std::random_access_iterator_tag>, bool> = true>
ArrayList(ITER begin, ITER end) : arr_size{ static_cast<size_type>(end - begin) }, arr_capacity{ arr_size }
{
std::uninitialized_copy(begin, end, array = allocator.allocate(arr_size));
first = array;
last = array + arr_size - 1;
}
这篇关于如何使构造函数接受所有类型的迭代器?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!