Notur
Notur

Reputation: 93

Implementing own begin() and end()

I've got this template:

template<typename C,class F>
class filtered_cont{
     C& container;
     F filter;
     class const_iterator{
     //my iterator implementation
     }
     const_iterator begin(){
     //...
     }
}

C- container and F is filter. I'd like to ask how to implement my own begin() method that it will return first valid element. I got something like this, but I get errors

const_iterator begin() const{
    for (const_iterator it=cont.begin(); it!=const_iterator(); it++) {
        if(pred(*it)) return it;
    }
    return const_iterator();
}

I think the wrong part is it=cont.begin(), but I don't really know how to get begin() iterator.

Error:

no viable conversion from 'iterator' (aka '__list_iterator<value_type, __void_pointer>') to 'filter_view<std::__1::list<unsigned char,
      std::__1::allocator<unsigned char> >, is_even>::const_iterator

Upvotes: 2

Views: 2488

Answers (3)

RichardPlunkett
RichardPlunkett

Reputation: 2988

Your begin function looks fine (in pri).

Instead of defining a const_iterator type, you may want to define a iterator type, and then define the const_iterator type as the const version of it.

But, regardless, your class will need to provide a way to get from an arbitrary input iterator, to the desired type of iterator. That means you needs constructor, and a general approach. I am not certain how one should do that, but I would guess your own iterator stores the incoming iterator (in a C::iterator field), then passes on any calls to it.

Upvotes: 0

Dietmar K&#252;hl
Dietmar K&#252;hl

Reputation: 153830

The error message states what is missing: your const_iterator needs an [implicit] constructor from typename Container::const_iterator:

template <typename C, typename F>
class filtered_cont<C, F>::const_iterator {
public:
    const_iterator(typename C::const_iterator it);
    // ...
};

If you change your initialization slightly, you can make the conversion explicit which is probably a good idea:

for (const_iterator it(cont.begin()); ... ) {
    ...
}

Personally, I would expect to use the filtering logic to be contained by the iterator as it needs to have this logic anyway, e.g., when moving to the next element. The logic itself should probably be

std::find_if(it, cont.end(), filter);

Upvotes: 0

Vaughn Cato
Vaughn Cato

Reputation: 64308

You'll need to use the container's iterator, not your own. Something like this:

const_iterator begin() const{
    for (typename C::const_iterator it=cont.begin(); it!=cont.end(); it++) {
        if(pred(*it)) return const_iterator(it);
    }
    return const_iterator();
}

Upvotes: 2

Related Questions