Универсальный итератор

Я пытаюсь найти общий способ доступа к набору контейнеров. У меня есть стандартный вектор и список в дополнение к другому настраиваемому списку.

Пользовательский список определяет итератор;

class Iterator: public std::iterator<std::forward_iterator_tag, T> {
    // ...
}

Iterator begin() {
    return (Iterator(root));
}

Iterator end() {
    return (Iterator(NULL));
}

с перегруженными соответствующими операторами.

В идеале я бы хотел это сделать;

class Foo {
public:
    Foo() {
        std::list<int> x;
        std::vector<int> y;
        custom_list<int> z;

        iter = x.begin(); // OR
        iter = y.begin(); // OR
        iter = z.begin();

        // ...
    };
private:
    std::iterator<int> iter;
};

Но очевидно, что это все итераторы разных типов. Однако я могу предположить, что все контейнеры одного типа.

Есть ли элегантный способ решить эту проблему?

Ответов (3)

Решение

Вот несколько статей, которые могут вас заинтересовать

Предоставление итераторам STL базового класса

Стирание типов для итераторов C++

Ссылка на класс any_iterator

Лучше поздно, чем никогда...

Появился последний выпуск C-Vu и угадайте, что в нем было: верно, итераторы, которые делают именно то , что вы хотели.

К сожалению, вам нужно стать членом ACCU, чтобы просматривать журнал (статья ссылается на статью Overload 2000 года, на которую ссылается Дэвид). Но за ничтожную цену в год вы получаете хороший журнал для чтения, конференции и группы пользователей. Когда вы станете участником, вы сможете просматривать старые выпуски в формате PDF, так чего же вы ждете?

Случай быть осторожным в своих просьбах. Классы any_iterator, которые вы видите, работают с неограниченным набором типов итераторов. У вас их всего три, о которых вы знаете заранее. Конечно, вам может потребоваться добавить четвертый тип в будущем, но что с того, что для этого потребуется O (1) дополнительных строк кода?

Большим преимуществом закрытого набора возможных содержащихся типов является то, что у вас есть верхняя граница для sizeof (), что означает, что вы можете избежать кучи и косвенного обращения, которое она приносит. По сути, поместите их все в boost :: variant и вызовите apply_visitor.