1

I have arrays like:

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

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

F<S1> arr1[10];

I'm looking for an iterator (or iterator-like class) to simplify the following:

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

Would like something a bit cleaner that can work with different types S1, S2, etc..

chriskirk
  • 761
  • 1
  • 11
  • 22
  • Do you want to use different types S1,S2 in the same array while iterating over the array? If F is only a wrapper for optional values, have you considered to use [boost::optional](http://www.boost.org/doc/libs/1_48_0/libs/optional/doc/html/index.html)? – P3trus Feb 16 '12 at 21:15
  • See also: http://stackoverflow.com/questions/4857892/defining-iterator-of-my-own-container – Chris Huang-Leaver Jun 14 '12 at 07:58

3 Answers3

8

The standard provides iterators for arrays:

#include <iterator>

T arr[100];

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

The type of it will just be T *, but this gives you a uniform interface.

The term "iterator" really just refers to a concept rather than any particular piece of code. Naked pointers are perfectly legitimate iterators. What matters is that std::iterator_traits gives the correct typedefs, which it does for naked pointers.

Kerrek SB
  • 464,522
  • 92
  • 875
  • 1,084
  • 1
    @chriskirk: This is trivial to write yourself: `template T * begin(T (arr&)[N]) { return arr; }`, and `arr + N` for `end`. – Kerrek SB Feb 17 '12 at 23:54
3

you can make your own iterator using the Boost Iterator library, especially iterator_facade

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

Chris Huang-Leaver
  • 6,059
  • 6
  • 41
  • 67
Joel Falcou
  • 6,247
  • 1
  • 17
  • 34
2

Really you're looping until you find an F which isn't set.

Use 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>);
}
Peter Wood
  • 23,859
  • 5
  • 60
  • 99