I'm currently writing an Polynomial
-class in C++, which should represent an polynomial of the following form:
p(x) = a_0 + a_1*x^1 + a_2*x^2 + ... + a_i*x^i
where a_0, ..., a_i
are all int
's.
The class internally uses an member variable a_
of typestd::vector<int>
to store the constant factors a_0, ..., a_i
. To access the constant factors the operator[]
is overloaded in the following way:
Read and write:
int &operator[](int i)
{
return a_.at(i);
}
This will fail when trying to change one of the factors a_i
with:
i > degree of polynomial = a_.size() - 1
Read-only:
int operator[](int i) const
{
if (i > this->degree()) {
return 0;
}
return a_.at(i);
}
The slightly different implementation allows rather comfortable looping over the factors of two different sized polynomials (without worrying about the degree of the polynomial).
Sadly I seem to miss something here, since the operator+
-overloading (which makes use of this comfortable read-only-operator[]
) fails.
operator+
-overloading:
Polynomial operator*(const Polynomial &other) {
Polynomial res(this->degree() + other.degree());
for (int i = 0; i <= res.degree(); ++i) {
for (int k = 0; k <= i; ++k) {
res[i] += (*this)[k] * other[i-k];
}
}
return res;
}
Don't mind the math involved. The important point is, that the i
is always in the range of
0 <= i < res.a_.size()
thus writing to res[i]
is valid. However (*this)[k]
and other[i-k]
try to read from indices which don't necessarily lay in the range [0, (*this).a_.size() - 1]
.
This should be fine with our read-only-implementation of the operator[]
right? I still get an error trying to access a_
at invalid indices. What could cause the compiler to use the read-write-implementation in the line:
res[i] += (*this)[k] * other[i-k];
Especially the part on the right side of the equality.
I'm certain the error is caused by the "wrong" use of the read-and-write-operator[]
. Because with an additional check fixes the invalid access:
if (k <= this->degree() && i-k <= other.degree()) {
res[i] += (*this)[k] * other[i-k];
}
What am I missing with the use of the operator[]
-overloading? Why isn't the read-only-operator[]
used here?
(*this)[k]
is using the non-const this
as the function containing it is not const
.
Hence the non-const overload of []
is preferred by the compiler.
You could get round this using an ugly const_cast
, but really you ought to keep the behaviour of the two versions of the []
operator as similar as possible. Besides, the std::vector
overload of []
doesn't insist on the index being bounds checked, as opposed to at
which must be. Your code is a deviation from this and therefore could confuse readers of your code.