【发布时间】:2021-04-01 08:41:35
【问题描述】:
在 libstdc++3 中,在头文件 bits/stl_iterator.h(GCC 10 源代码here)中,__normal_iterator 的每个二元运算符都有两个重载已定义(这里以== 为例):
template<typename _IteratorL, typename _IteratorR, typename _Container>
_GLIBCXX20_CONSTEXPR
inline bool
operator==(const __normal_iterator<_IteratorL, _Container>& __lhs,
const __normal_iterator<_IteratorR, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() == __rhs.base(); }
template<typename _Iterator, typename _Container>
_GLIBCXX20_CONSTEXPR
inline bool
operator==(const __normal_iterator<_Iterator, _Container>& __lhs,
const __normal_iterator<_Iterator, _Container>& __rhs)
_GLIBCXX_NOEXCEPT
{ return __lhs.base() == __rhs.base(); }
在这种情况下,.base() 返回指向数组元素的指针。这在整个库中也针对其他迭代器类型完成。根据散布在各处的 cmets 和变更日志,这样做是为了支持 iterators 和 const_iterators 之间的互操作性。
我的问题是,为什么 <_IteratorL, _IteratorR, _Container> 和 <_Iterator, _Container> 都为它们定义了重载?也就是说,为什么需要<_Iterator, _Container>?前者不会涵盖所有情况吗?如果后者被删除会破坏什么?
GCC 的 libstdc++ 实现有很多街头信誉,所以我确信有一个很好的,可能是微妙的原因,但我不知道它可能是什么。
我之所以问,是因为我目前正在解决我自己的自定义迭代器实现中的一些问题,并将 STL 视为一个模型。
【问题讨论】:
-
第二个重载允许隐式转换...第一个可能由于推导失败而导致转换失败(如果它是用户定义的转换)。
-
(My second attempt 也失败了。)
-
看来我错了:godbolt.org/z/9fGvja -- 我认为这会起作用(扣除会失败,但过载仍然可行)。现在我很困惑:)
标签: c++ templates stl iterator libstdc++