Reputation: 93
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
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
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
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