I'd like to specialize std::iterator_traits<>
for iterators of a container class template that does not have the usual nested typedefs (like value_type
, difference_type
, etc.) and whose source I shouldn't modify. Basically I'd like to do something like this:
template <typename T> struct iterator_traits<typename Container<T>::iterator>
{
typedef T value_type;
// etc.
};
except that this doesn't work, as the compiler is unable to deduce T
from Container<T>::iterator
.
Is there any working way to achieve the same?
For example:
template <typename T>
class SomeContainerFromAThirdPartyLib
{
typedef T ValueType; // not value_type!
// no difference_type
class iterator
{
typedef T ValueType; // not value_type!
// no difference_type
...
};
iterator begin() { ... }
iterator end() { ... }
...
};
Now suppose I call std::count()
using an instance of this class. As far as I know, in most STL implementations, count()
returns iterator_traits<Iterator>::difference_type
. The primary template of iterator_traits<I>
simply does typedef typename I::difference_type difference_type
. Same with the other nested types.
Now in our example this obviously won't work, as there's no Container::iterator::difference_type
. I thought I could work around this without modifying the iterator class, by specializing iterator_traits
for iterators of any Container<T>
.
In the end, I just want to be able to use std algorithms like count, find, sort, etc., preferably without modifying any existing code. I thought that the whole point of iterator_traits
is exactly that: being able to specify types (like value_type
, diff_type
etc.) for iterator types that do not support them built-in. Unfortunately I can't figure out how to specialize the traits class for all instances of Container<T>
.
Yes. The compiler cannot deduce T
from Container<T>::iterator
because it is non-deducible context, which in other words means, given Container<T>::iterator
, the value of T
cannot uniquely and reliably be deduced (see this for detail explanation).
The only solution to this problem is that you've to fully specialize iterator_traits
for each possible value of iterator
which you intend to use in your program. There is no generic solution, as you're not allowed to edit the Container<T>
class template.