I'm trying to define an interface for a container, one of which instances will be a vector
. A problem is that I want it to be iterable.
struct Iconstraint_iterator {
using difference_type = std::ptrdiff_t;
using value_type = ref<Expr>;
using pointer = value_type *;
using reference = value_type &;
using iterator_category = std::input_iterator_tag;
virtual ~Iconstraint_iterator() {}
virtual const value_type &operator*() = 0;
};
struct constraint_iterator : public Iconstraint_iterator {
using difference_type = std::ptrdiff_t;
using value_type = ref<Expr>;
using pointer = value_type *;
using reference = value_type &;
using iterator_category = std::input_iterator_tag;
using iterator = std::vector<value_type>::const_iterator;
constraint_iterator(iterator ptr) : ptr(ptr) {}
virtual const value_type &operator*() { return *ptr; }
private:
iterator ptr;
};
class IConstraints {
public:
virtual ~IConstraints() {}
virtual Iconstraint_iterator begin() const = 0;
virtual Iconstraint_iterator end() const = 0;
virtual void push_back(ref<Expr>) = 0;
};
struct Constraints : public IConstraints {
virtual constraint_iterator begin() const {
return constraint_iterator(constraints.cbegin());
}
virtual Iconstraint_iterator end() const {
return constraint_iterator(constraints.cend());
}
virtual void push_back(ref<Expr> c) { constraints.push_back(c); }
private:
std::vector< ref<Expr> > constraints;
};
IConstraints
is my interface and Constraints
is ought to be it's vector
-based instance. Consider different code fragments for Constraints::begin()
and Constraints::end()
, which are both rejected by the compiler as follows.
error: virtual function 'begin' has a different return type ('constraint_iterator')
than the function it overrides (which has return type 'Iconstraint_iterator')
[build] virtual constraint_iterator begin() const {
[build] ~~~~~~~~~~~~~~~~~~~ ^
[build] note: overridden virtual function is here
[build] virtual Iconstraint_iterator begin() const = 0;
[build] ~~~~~~~~~~~~~~~~~~~~ ^
[build] error: allocating an object of abstract class type 'Iconstraint_iterator'
[build] return constraint_iterator(constraints.cend());
[build] ^
[build] note: unimplemented pure virtual method 'operator*' in 'Iconstraint_iterator'
[build] virtual const value_type &operator*() = 0;
I do not understand why the compiler complains as constraint_iterator
inherits Iconstraint_iterator
.
If my code idea is totally wrong, could you provide another way to make an iterable container interface with vector as one of it's instances?