我正在尝试编写我的向量,使其尽可能类似于 STL 版本,我使用了这些类型名称。
using value_type = Type;
using iterator = vector_iterator<value_type>;
using const_iterator = const vector_iterator<value_type>;
using reverse_iterator = std::reverse_iterator<iterator>;
using const_reverse_iterator = std::reverse_iterator<const_iterator>;
并实现了很多方法,包括以下迭代器相关的方法。
constexpr iterator begin() noexcept;
constexpr const_iterator begin() const noexcept;
constexpr const_iterator cbegin() const noexcept;
constexpr iterator end() noexcept;
constexpr const_iterator end() const noexcept;
constexpr const_iterator cend() const noexcept;
constexpr reverse_iterator rbegin() noexcept;
constexpr const_reverse_iterator rbegin() const noexcept;
constexpr const_reverse_iterator crbegin() const noexcept;
constexpr reverse_iterator rend() noexcept;
constexpr const_reverse_iterator rend() const noexcept;
constexpr const_reverse_iterator crend() const noexcept;
就像STL中的标准向量一样,每个
begin()
、end()
、rbegin()
和rend()
都有两个重载,返回一个非常量迭代器和一个常量迭代器。 cbegin()
、cend()
和 crbegin()
、crend()
被视为返回 const 迭代器的方法的别名。
每组实现看起来像这样(例如
begin()
和rend()
):
// non-const version of begin()
template <typename Type, typename Allocator>
constexpr typename vector<Type, Allocator>::iterator vector<Type, Allocator>::begin() noexcept
{
return iterator(ptr_data_);
}
// const version of begin()
template <typename Type, typename Allocator>
constexpr typename vector<Type, Allocator>::const_iterator vector<Type, Allocator>::begin() const noexcept
{
return const_iterator(ptr_data_);
}
// cbegin()
template <typename Type, typename Allocator>
constexpr typename vector<Type, Allocator>::const_iterator vector<Type, Allocator>::cbegin() const noexcept
{
return const_iterator(ptr_data_);
}
// non-const version of rend()
template <typename Type, typename Allocator>
constexpr typename vector<Type, Allocator>::reverse_iterator vector<Type, Allocator>::rend() noexcept
{
return reverse_iterator(begin());
}
// const version of rend()
template <typename Type, typename Allocator>
constexpr typename vector<Type, Allocator>::const_reverse_iterator vector<Type, Allocator>::rend() const noexcept
{
return const_reverse_iterator(begin());
}
// crend()
template <typename Type, typename Allocator>
constexpr typename vector<Type, Allocator>::const_reverse_iterator vector<Type, Allocator>::crend() const noexcept
{
return const_reverse_iterator(cbegin());
}
然后,当我尝试运行测试项目时,Visual Studio告诉我,
const
版本的begin()
、const
版本的end()
、cbegin()
和cend()
由于重新定义而触发C2373
错误.
C2373 'clb_container::vector
::begin': 重新定义;不同类型修饰符 C2373 'clb_container::vector
::cbegin': 重新定义;不同类型修饰符 C2373 'clb_container::vector
::end': 重新定义;不同类型修饰符 C2373 'clb_container::vector
::cend': 重新定义;不同类型修饰符
这是我的
vector_iterator
的构造函数:
template <typename Type>
vector_iterator<Type>::vector_iterator(pointer ptr)
{
iterator_ptr_ = ptr;
}
template <typename T>
vector_iterator<T>::vector_iterator(const vector_iterator& target)
{
iterator_ptr_ = target.iterator_ptr_;
}
我确信我没有两次定义这些方法。
我已尝试以下步骤:
const
版本的begin()
、const
版本的end
、cbegin()
和cend()
之一可用,C2373
就会再次出现。C2373
消失,程序编译正常。但是,如果我将“平台工具集”更改回默认的“Visual Studio 2022(v143)”,则会再次出现错误。所以我认为这个问题很可能是由 Visual C++ 2022 引起的。但是,作为我小小的STL的一部分,我希望它能够在大多数编译器下正常编译,而不是因为一些莫名其妙的原因而失败,尤其是在像Visual Studio这样用户众多的平台上,但我仍然找不到真正的问题.
constexpr
意味着const
...
constexpr iterator begin() noexcept;
constexpr const_iterator begin() const noexcept;
是相同的东西,除了返回类型。并且您不能执行仅返回类型不同的重载。