C ++ простая реализация итератора - PullRequest
1 голос
/ 17 февраля 2012

У меня есть массивы вроде:

template<class T> class F
{
   ...
   bool isSet() { return set_; }
   T& GetVal() { return val_; }

private:
   T val_;
   bool set_; 
   ...
}

F<S1> arr1[10];

Я ищу итератор (или подобный итератору класс), чтобы упростить следующее:

F<S1>* cur = arr1[0];
while(cur.IsSet())
{
   S1* ptr = cur->GetVal();
   // do something with ptr
   cur++;
};

Хотелось бы что-нибудь немного чище, которое может работать с различными типами S1, S2 и т. Д.

Ответы [ 3 ]

8 голосов
/ 17 февраля 2012

Стандарт предоставляет итераторы для массивов:

#include <iterator>

T arr[100];

for (auto it = std::begin(arr), end = std::end(arr); it != end; ++it)
{
    foo(*it);
    it->zap();
}

Тип it будет просто T *, но это дает вам единый интерфейс.

Термин «итератор» на самом деле относится к концепции , а не к какому-либо конкретному коду. Голые указатели - совершенно законные итераторы. Важно то, что std::iterator_traits дает правильные typedefs, что и для голых указателей.

3 голосов
/ 17 февраля 2012

вы можете создать свой собственный итератор, используя библиотеку Boost Iterator, особенно iterator_facade

http://www.boost.org/doc/libs/1_49_0/libs/iterator/doc/iterator_facade.html

2 голосов
/ 17 февраля 2012

На самом деле вы зацикливаетесь, пока не найдете F, который не установлен.

Использование std::find_if:

#include <algorithm>
#include <iterator>

template<typename Type>
bool doSomethingOrStopIfNotSet(F<Type>& object)
{
    const bool isSet = object.isSet(); 
    if(isSet)
    {
        // do something
    }
    return !isSet; // return false so that find_if keeps looking
}

int main()
{
    F<int> arr[100];
    std::find_if(std::begin(arr), std::end(arr), doSomethingOrStopIfNotSet<int>);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...