Reputation: 2734
I'm developing a class that must return an iterator with the begin()
method. Also, I have to develop a function that receives a const reference of this class and iterates over it.
When I try to get an iterator from this method, I have the following compilation error: "the object has type qualifiers that are not compatible with the member function."
I can't understand why this error appears.
Here is the code that I have written:
// ------------ class Neuron -------------
class Neuron { ... };
// ---------------------------------
// ------------ class AbstractLayer -------------
class AbstractLayer {
public:
class Iterator : public std::iterator<std::input_iterator_tag, Neuron> {
public:
Iterator(Neuron *neurons) : _neurons(neurons) {}
private:
Neuron *_neurons;
};
virtual Iterator begin() = 0;
virtual const Iterator begin2() = 0;
};
// ----------------------------------------
// ------------ class Layer -------------
class Layer : AbstractLayer {
public:
Layer(){};
Iterator begin(){ return Iterator(_neurons); }
const Iterator begin2(){ return (const Iterator)begin(); }
private:
Neuron *_neurons;
int _size;
};
// --------------------------------
// ------------ Method where the problem is -------------------
void method(const AbstractLayer &layer){
// Error in both methods:
// "the object has type qualifiers that are not compatible with the member function."
layer.begin();
layer.begin2();
}
// -------------------------------------------------------------
Upvotes: 3
Views: 2092
Reputation: 41092
Your function accepts a const AbstractLayer
which means that only const
member functions can be called on it. However, begin
and begin2
are not const
. In fact, given that only begin2
returns a const Iterator
, it wouldn't make sense to try and call begin
anyway in this method.
Change
virtual const Iterator begin2() = 0;
to
virtual const Iterator begin2() const = 0;
and
const Iterator begin2()
to
const Iterator begin2() const
Finally, returning a const Iterator
is actually meaningless in your code, as the const
is discarded on account of an rvalue being returned. Regardless, you shouldn't need to perform casting to const Iterator
when you call begin
; just return an Iterator
and the compiler will take care to make it const.
Finally, your Layer
class needs to derive publicly from AbstractLayer
:
class Layer : public AbstractLayer
Upvotes: 0
Reputation: 263
In method
, the layer
argument is const which prevents you from calling non-const methods on it. If you take layer by non-const reference (void method(AbstractLayer &layer)
), you will be able to call both methods.
You should probably provide a const begin
method that returns a const_iterator
so you can iterate over a const AbstractLayer
.
Upvotes: 0
Reputation: 62553
You do not need begin
and begin2
. What you need is two versions of begin
- const and non-const. A const one would return const iterator. You also might want a cbegin
(const only) which would always return const iterator.
Upvotes: 0
Reputation: 409146
In the method
function, layer
references a constant object. That means you can only call functions marked as const
. Like e.g.
class AbstractLayer {
public:
...
virtual const Iterator begin() const = 0; // <- Note use of `const` here
...
};
Upvotes: 4