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*() const
和 pointer operator->() const
、
因为 reference
会是 const_reference
而 const_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_reference
是 const T&
就不是问题,因为根据 const 折叠规则 const const_reference
就是 const T&
,这正是您想要的。
我正在尝试使用迭代器实现自定义标准兼容容器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*() const
和 pointer operator->() const
、
因为 reference
会是 const_reference
而 const_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_reference
是 const T&
就不是问题,因为根据 const 折叠规则 const const_reference
就是 const T&
,这正是您想要的。