Универсальный итератор
-
08-06-2019 - |
Вопрос
Я пытаюсь найти общий способ доступа к набору контейнеров.У меня есть стандартный вектор и список в дополнение к другому пользовательскому списку.
Пользовательский список определяет итератор;
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;
};
Но очевидно, что это все итераторы разных типов.Однако я могу предположить, что все контейнеры одного типа.
Есть ли элегантный способ решить эту проблему?
Решение
Вот несколько статей, которые могут вас заинтересовать
Предоставление итераторам STL базового класса
Другие советы
Лучше поздно, чем никогда...
Последний выпуск C-Ву Подвернулся и угадай, что в нем было:Правильно, итераторы, которые делают точно то, что ты хотел.
К сожалению, вам необходимо стать участником АККУ просмотреть журнал (статья ссылается на статью Overload 2000 года, на которую ссылается Дэвид).Но за жалкую цену в год вы получаете хороший журнал для чтения, конференции и группы пользователей.Став участником, вы сможете просматривать старые выпуски в формате PDF, чтобы чего же ты ждешь?
Случай осторожности в том, о чем просишь.Классы Any_iterator, которые вы видите, работают с неограниченным набором типов итераторов.У вас есть только три, о которых вы знаете заранее.Конечно, в будущем вам может понадобиться добавить четвертый тип, но что, если для этого потребуется O(1) дополнительных строк кода?
Большим преимуществом закрытого набора возможных содержащихся типов является то, что у вас есть верхняя граница для sizeof(), что означает, что вы можете избежать кучи и связанной с ней косвенности.По сути, поместите их все в boost::variant и вызовите apply_visitor.