While studying various std::vector
's iterator implementations, I noticed this copy-constructor which uses SFINAE to allow initializing constant iterators from non-constant ones and vice versa:
// 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()) { }
It's a common knowledge that the iterators for vectors are defined this way:
typedef __gnu_cxx::__normal_iterator<pointer, vector> iterator;
typedef __gnu_cxx::__normal_iterator<const_pointer, vector>
const_iterator;
I can't understand how the checking of container's pointer
type against Iter
allows the conversion. 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?
Could you please explain how this constructor works and maybe bring an example of such substitution?
P.S.
Another question is why std::list
doesn't use the same technique of avoiding code duplication by declaring iterators like this. It has two separate classes for both versions of iterators. I wonder if it's possible to implement list's iterators in the very same way as vector's
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?
Yes, that's exactly what happens, because that definition would be an ambiguous overload of the default (implicit) copy constructor. These extra constructors are there to allow the implicit conversion to happen only from non-const to const iterator, and explicit conversion from pointer-like types to iterators.
As for std::list
, I don't know! It could simply be an arbitrary implementation detail, or maybe this way was considered to be more readable/maintainable.