Reputation: 859
I'm implementing a class Aviary, which can store pointers to Bird-objects. Now, I have the following:
class Aviary {
public:
const Bird &operator[](const size_t index) const {
return birds[index];
}
Bird &operator[](const size_t index) {
return birds[index];
}
private:
std::vector<Bird*> birds;
The Bird-objects are stored as pointers in order to avoid object-slicing. However, there is a problem with the operator[]-implementation (Reference to type 'const Bird' could not bind to an lvalue of 'const value_type' (aka 'Bird *const')).
How do I implement the operator[] properly?
Upvotes: 0
Views: 255
Reputation: 11028
Two side notes:
const
in a parameter passed by value (const size_t index
) is useless and your compiler will ignore it. You can try declaring it with const
and removing the const
in the implementation: the compiler will correctly consider that your implementation matches the declaration.const
version of operator[]
is as follows:As follows
Bird &operator[](size_t index) {
return const_cast<Bird&>(const_cast<const Aviary*>(this)->operator[](index));
}
I know all those const_cast
look ugly, but they are both safe and this is the right way to ensure that both versions of operator[]
do the same (you just need to maintain the const
version from now on), while also making sure that your are not doing any non-const
operation in the const
version.
Apart from that, the problem with your code is that you are returning pointers, not (references to) the values pointed by them, as Luchian and ForEveR have already pointed out.
Upvotes: 1
Reputation: 55887
Since you store pointers, you should dereference
the pointer for return reference.
const Bird &operator[](const size_t index) const {
return *birds[index];
}
Bird &operator[](const size_t index) {
return *birds[index];
}
Side note: use smart pointers, instead of raw pointers.
Upvotes: 1
Reputation: 258568
You need to dereference:
return *(birds[index]);
birds[index]
is a Bird*
, so you can't directly return it as a Bird&
.
Upvotes: 0