специализирующийся на iterator_traits

Я хотел бы специализировать std :: iterator_traits <> для итераторов шаблона класса контейнера, который не имеет обычные вложенные определения типов (например, value_type , difference_type и т. д.) и исходный код которых мне не следует изменять. В основном я хотел бы сделать что-то вроде этого:

template <typename T> struct iterator_traits<typename Container<T>::iterator> 
{
    typedef T value_type; 
    //  etc.
}; 

, за исключением того, что это не работает, поскольку компилятор не может вывести T из Container :: iterator .

Есть ли какой-нибудь рабочий способ достичь того же?


Например:

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() { ... }
    ...
}; 

Теперь предположим, что я вызываю std :: count () , используя экземпляр этого класса. Насколько мне известно, в большинстве реализаций STL count () возвращает iterator_traits :: difference_type . Первичный шаблон iterator_traits просто выполняет typedef typename I :: difference_type difference_type . То же самое с другими вложенными типами.

В нашем примере это явно не сработает, поскольку нет Container :: iterator :: difference_type . Я думал, что могу обойти это, не изменяя класс итератора, специализируя iterator_traits для итераторов любого Container .

В конце концов, я просто хочу иметь возможность использовать стандартные алгоритмы, такие как подсчет, поиск, сортировка и т. Д., желательно без изменения существующего кода. Я думал, что вся суть iterator_traits как раз в том, что возможность указывать типы (например, value_type , diff_type и т. Д.) Для типов итераторов, которые не поддерживают их встроенные. К сожалению, я не могу понять, как специализировать класс признаков для всех экземпляров Container .

8
задан imre 28 October 2011 в 11:57
поделиться