2008-08-13 10 views
29

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

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

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; 
}; 

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

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

ответ

19

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

Giving STL Iterators a Base Class

Type Erasure for C++ Iterators

any_iterator Class Reference

+3

У Томаса Беккера (автора второй ссылки выше) есть более длинная статья, которая превосходна: http://www.artima.com/cppsource/type_erasure.html – Adrian 2009-01-09 17:04:16

+0

@Adrian - эта статья была блестящей: D спасибо за то, что поделились ею ! – nevelis 2014-08-08 02:20:20

2

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

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

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

1

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

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