2

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

3 Answers 3

2

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();
}
Sign up to request clarification or add additional context in comments.

2 Comments

I've tried that, I get this error then no matching conversion for functional-style cast from 'typename list<unsigned char, allocator<unsigned char> >::const_iterator' (aka '__list_const_iterator<value_type, __void_pointer>') to 'filter_view<std::__1::list<unsigned char, std::__1::allocator<unsigned char> >, is_even>::const_iterator'
@James: You'll need to have a constructor for filtered_cont::const_iterator that takes the other iterator as a parameter.
0

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

Comments

0

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.

1 Comment

A const_iterator is not the const version of iterator, any more than char const * is like char * const

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.