c++ allocator traits reference and const_reference missing and iterator to const iterator 转换

c++ allocator traits reference and const_reference missing and iterator to const iterator conversion

我正在尝试使用迭代器实现自定义标准兼容容器class。
为此,我开始定义容器 class 和迭代器的特征要使用的 public 类型定义。
我想让它与 c++17 兼容,并尽量不使用 c++20 删除的功能或不推荐使用 c++17。
这是我得到的:

template <typename T, typename Alloc = std::allocator<T>>
class container {
    using allocator_type = Alloc;
    using value_type = std::allocator_traits<Alloc>::value_type;
    using pointer = std::allocator_traits<Alloc>::pointer;
    using const_pointer = std::allocator_traits<Alloc>::const_pointer;
    using reference = value_type&; // <-- here 
    using const_reference = const value_type&; // <-- here 
    using difference_type = std::allocator_traits<Alloc>::difference_type;
    using size_type = std::allocator_traits<Alloc>::size_type;

    class iterator;
};

template <typename T, typename Alloc = std::allocator<T>>
class container::iterator {
    using value_type = std::allocator_traits<Alloc>::value_type;
    using pointer = std::allocator_traits<Alloc>::pointer;
    using const_pointer = std::allocator_traits<Alloc>::const_pointer;
    using reference = value_type&; // <-- here 
    using const_reference = const value_type&; // <-- here
    using difference_type = std::allocator_traits<Alloc>::difference_type;
    using size_type = std::allocator_traits<Alloc>::size_type;
};

我是否必须像我在示例中所做的那样定义引用和 const_reference 类型,或者是否有另一种标准方法来定义它? 另一个问题是如何在不复制我的迭代器的情况下定义 const_iterator。
有人说我应该用值类型模板化我的迭代器,有人说我只是写一个新的迭代器。
如果我要模板,我不知道如何为它创建正确的类型特征,所以我的 std 函数定义:
reference operator*() constpointer operator->() const
因为 reference 会是 const_referenceconst_reference 在技术上会是 const const_reference.
例如:

template <typename T>
class container {
    
    template <typename ValueType>
    class iterator;

    using iterator = iterator<T>;
    using const_iterator = iterator<const T>;
};

template <typename ValueType>
class container::iterator {
public:
    using value_type = ValueType;
    using pointer = value_type*;
    using const_pointer = const value_type*;
    using reference = value_type&;
    using const_reference = const value_type&;

    reference operator*() const;
    pointer operator->() const;
};

Do i have to define reference and const_reference types myself like i did in the example

是的。分配器不知道你的容器是如何实现的,所以它不知道如何定义那些类型别名。

Another question would be how to define a const_iterator without duplicating my iterator.

借助模板的魔力。 iterator<T> 对比 iterator<const T>.

because reference would be const_reference and const_reference would be technically const const_reference

只要 const_referenceconst T& 就不是问题,因为根据 const 折叠规则 const const_reference 就是 const T&,这正是您想要的。