矢量迭代器的复制构造函数如何使用 SFINAE 允许迭代器到 const_iterator 转换?
How vector iterator's copy-constructor use SFINAE to allow for iterator to const_iterator conversion?
在研究各种 std::vector
的迭代器实现时,我注意到这个复制构造函数使用 SFINAE 允许从非常量迭代器初始化常量迭代器,反之亦然:
// Allow iterator to const_iterator conversion
// ...
// N.B. _Container::pointer is not actually in container requirements,
// but is present in std::vector and std::basic_string.
template<typename _Iter>
__normal_iterator(const __normal_iterator<_Iter,
typename __enable_if<
(std::__are_same<_Iter, typename _Container::pointer>::__value),
_Container>::__type>& __i) : _M_current(__i.base()) { }
众所周知,向量的迭代器是这样定义的:
typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;
typedef __gnu_cxx::__normal_iterator<const_pointer, vector>
const_iterator;
我不明白根据 Iter
检查容器的 pointer
类型如何允许转换。如果我传递一个常量迭代器,Iter
应该是 const_pointer
,那会不会使 enable_if<>
检查失败并从集合中丢弃这个构造函数?那要用哪一个呢?
你能解释一下这个构造函数是如何工作的吗?也许可以举一个这种替换的例子?
P.S。
另一个问题是为什么 std::list
不使用通过像这样声明迭代器来避免代码重复的相同技术。对于两个版本的迭代器,它都有两个单独的 类。我想知道是否有可能以与 vector
完全相同的方式实现列表的迭代器
If I pass a constant iterator, Iter should be const_pointer, won't that fail the enable_if<> check and discard this constructor from the set? Which one will be used then?
是的,这正是发生的情况,因为该定义将是默认(隐式)复制构造函数的模糊重载。这些额外的构造函数允许 隐式 仅从非常量迭代器到 const 迭代器,以及从类指针类型到迭代器的显式转换。
至于std::list
,我不知道!它可能只是一个任意的实现细节,或者这种方式被认为更 readable/maintainable.
在研究各种 std::vector
的迭代器实现时,我注意到这个复制构造函数使用 SFINAE 允许从非常量迭代器初始化常量迭代器,反之亦然:
// Allow iterator to const_iterator conversion
// ...
// N.B. _Container::pointer is not actually in container requirements,
// but is present in std::vector and std::basic_string.
template<typename _Iter>
__normal_iterator(const __normal_iterator<_Iter,
typename __enable_if<
(std::__are_same<_Iter, typename _Container::pointer>::__value),
_Container>::__type>& __i) : _M_current(__i.base()) { }
众所周知,向量的迭代器是这样定义的:
typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;
typedef __gnu_cxx::__normal_iterator<const_pointer, vector>
const_iterator;
我不明白根据 Iter
检查容器的 pointer
类型如何允许转换。如果我传递一个常量迭代器,Iter
应该是 const_pointer
,那会不会使 enable_if<>
检查失败并从集合中丢弃这个构造函数?那要用哪一个呢?
你能解释一下这个构造函数是如何工作的吗?也许可以举一个这种替换的例子?
P.S。
另一个问题是为什么 std::list
不使用通过像这样声明迭代器来避免代码重复的相同技术。对于两个版本的迭代器,它都有两个单独的 类。我想知道是否有可能以与 vector
If I pass a constant iterator, Iter should be const_pointer, won't that fail the enable_if<> check and discard this constructor from the set? Which one will be used then?
是的,这正是发生的情况,因为该定义将是默认(隐式)复制构造函数的模糊重载。这些额外的构造函数允许 隐式 仅从非常量迭代器到 const 迭代器,以及从类指针类型到迭代器的显式转换。
至于std::list
,我不知道!它可能只是一个任意的实现细节,或者这种方式被认为更 readable/maintainable.