On segunda-feira, 10 de julho de 2017 22:21:10 PDT Giovanni Funchal wrote:
> I agree with Daniel's point that the 1:1 relation between container and
> iterator types is not currently mandated. However:
> - I believe it only affects (3).
Strictly speaking, yes. But (2) is also difficult to achieve. You're asking for
a way to transform an iterator to const_iterator, but those types are often
unrelated. For example, for libstdc++'s std::unordered_map, the two iterator
classes are just aliases to std::__detail::_Node_const_iterator and
std::__detail::_Node_iterator.
A const iterator is not the same as a const_iterator.
> - Due to std::iterator_traits<iterator>, iterators know something about
> their container (iterator_category) so there is already limited scope for
> an iterator to be used in multiple containers. BTW, perhaps
> std::iterator_traits<iterator>::iterator_container would be a better place
> for (3).
First, the category is the category of the iterator, not of the container.
Second, you cannot have a link back to the container, period. (3) is simply
unachievable. Just think of this, what should this be
std::iterator_traits<char *>::container
choose:
std::vector<char>
std::string
std::basic_string<char, any trait, any allocator> really...
std::array<char, N>
QVector<char>
QByteArray
> - I'm not sure I understand your claim that existing code would break. I
> envision it as a template specialized to std container's iterators and
> other container libraries could add their own specializations similarly to
> what is already done for example in std::hash.
Right, if you're adding a new set of functions and new members in the
template, existing generic code that isn't using those functions or those
members cannot break.
The problem is when people start using them, but their generic code works with
only a few containers that have been updated. When someone else tries to use
it with some non-updated container, it breaks.
There needs to be a good reason to do what you're asking.
> > I think 2 is possible though it may not necessarily have desirable
> > properties. It can have a generic implementation that returns a
> > std::const_iterator<Iterator> (where std::const_iterator is an adaptor
> > template similar to std::move_iterator). It can be partially specialized
> > on
> > T* to return const T* and then container libraries can add custom
> > overloads
> > for their own iterator types that will be found via ADL, but only if the
> > iterator type isn't T* or something like that.
>
> I like Brian's idea of std::const_iterator as an adaptor template.
std::const_itererator<iterator> is not std::const_iterator. That means that if
you tried to use this in generic code that actually used the container's
const_iterator, it would fail.
Just try:
void f(std::unordered_map<int, int>::const_iterator);
void g(std::unordered_map<int, int>::iterator it)
{
f(std::make_const_iterator(it));
}
--
Thiago Macieira - thiago (AT)
macieira.info - thiago (AT)
kde.org
Software Architect - Intel Open Source Technology Center