Reputation: 3891
I am learning C++ and studying Chapter 18 of Vandevoorde and Josuttis's C++ Templates. I retyped their code for Expression Templates, but the following is producing the error
sarray1.cpp:36:6: error: ‘T& SArray<T>::operator[](size_t) const’ cannot be overloaded
T& operator[] (size_t idx) const {
^
sarray1.cpp:32:5: error: with ‘T SArray<T>::operator[](size_t) const’
T operator[] (size_t idx) const {
Here's the code:
template <typename T>
class SArray {
public:
...
T operator[] (size_t idx) const {
return storage[idx];
}
T& operator[] (size_t idx) const {
return storage[idx];
}
...
};
I am just learning C++ so I hadn't seen an instance of an overloaded function that differed only be return type, but I see that this is indeed done: Overload a C++ function according to the return value. I also see that []
is not on the list of operators that cannot be overloaded in C++. I can't think of what else could be going wrong. What is the reason for the above error?
Upvotes: 2
Views: 4245
Reputation: 726509
You made a mistake when re-typing the code from page 323. Only the first overload should be const
, while the second one should be non-const
:
T operator[] (size_t idx) const {
return storage[idx];
}
T& operator[] (size_t idx) { // <<== No const here
return storage[idx];
}
The point this code is trying to illustrate is that you can overload an operator on const
-ness of this
object. C++ will figure out from the context which of the two operators it should call, and then either return a reference when SArray
is non-const, or return a copy when the array is const
.
Upvotes: 4
Reputation: 302817
You cannot overload by return type in C++. What's considered are the arguments and, for member functions, the qualification. In this case, I'm guessing what you meant to do was:
// a non-const member function to return a non-const reference
T& operator[] (size_t idx) {
return storage[idx];
}
// a const member function to return a const reference
const T& operator[] (size_t idx) const {
return storage[idx];
}
This way, the const
member function will be called if this
is a pointer to const
(because the non-const
function is not viable) and the non-const
function will be called otherwise (because it will be a better match).
Upvotes: 1
Reputation: 27133
Strictly speaking, you can't overload on the return type. If you read the question and answer that you linked (Overload a C++ function according to the return value), you would see that a workaround is required.
However, you really have to ask what you are doing this? Is there a simpler solution?
You probably should have one const
method, and one non-const
method:
const T& operator[] (size_t idx) const {
return storage[idx];
}
T& operator[] (size_t idx) {
return storage[idx];
}
Upvotes: 1