В коде:

//I know that to get this effect (being able to use it with std algorithms) I can inherit like I did in line below:

    class Iterator //: public std::iterator<std::bidirectional_iterator_tag,T>

    {
    private:
        T** itData_;
    public:
        //BUT I WOULD LIKE TO BE ABLE TO DO IT BY HAND AS WELL
        typedef std::bidirectional_iterator_tag iterator_category;
        typedef T* value_type;//SHOULD IT BE T AS value_type or T*?
        typedef std::ptrdiff_t difference_type;
        typedef T** pointer;//SHOULD IT BE T* AS pointer or T**?
        typedef T*& reference;//SHOULD IT BE T& AS reference or T*&?
};

В основном я спрашиваю, есть ли у меня переменная типа T ** в классе итератора, правильно ли предположить, что тип значения для этого итератора будет T * и так далее, как я описал в комментариях в коде, рядом с соответствующими строками .
Спасибо.

2
There is nothing we can do 18 Апр 2010 в 21:22
1
Внутренний формат данных не определяет типы интерфейсов. Внешний интерфейс, то есть operator * и operator ->, определяет типы интерфейса. Что возвращает operator *?
 – 
Potatoswatter
18 Апр 2010 в 22:19

2 ответа

Лучший ответ

Определение в стандарте (раздел 24.3.2):

template<class Category, class T, class Distance = ptrdiff_t,
         class Pointer = T*, class Reference = T&>
struct iterator {
    typedef T value_type;
    typedef Distance difference_type;
    typedef Pointer pointer;
    typedef Reference reference;
    typedef Category iterator_category;
};

Как видите, значения по умолчанию:

typedef T value_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef T& reference;

Предполагается, что итерация выполняется над контейнером элементов типа T. Если вместо этого ваш контейнер содержит элементы типа T*, определения типов в вашем вопросе будут правильными.

3
interjay 18 Апр 2010 в 21:36

Вы должны определить их такими, какими вы хотите их видеть. pointer и reference являются (такими же) типами, возвращаемыми операторами разыменования, которые вы будете определять для своего класса итератора (т. Е. operator->() и operator*() соответственно), поэтому то, что вы хотите, чтобы эти операторы возвращали, может помочь вам определить эти определения типов.

В комментарии вы предполагаете, что если бы вы унаследовали от std::iterator, это было бы от std::iterator<std::bidirectional_iterator_tag,T>. Вы можете заглянуть в Стандарт (как в ответе интерджея) или в свои файлы заголовков, чтобы увидеть, какие определения типов это предоставит, которые покажут вам, что вы хотите T, T* и T&, соответственно, чтобы быть таким же, как то, что это обеспечило бы.

2
John Marshall 18 Апр 2010 в 21:37