I'm trying to implement std::vector but I encountered the question.
According to C++ reference, std::vector::at
is like:
reference at (size_type n);
const_reference at (size_type n) const;
My question is: Why don't I use reference at (size_type n) const;
?
Thank you for any help or criticism!
Update: Thanks! I'm clear about that.
My fault is that I don't konw functions with and without const
are also a kind of overload. The original design is to use the one with const
when a const vector calls it, so it'll return a const_reference. When a vector which is not const, then the return value shouldn't be const_reference.
But if we make the 2 functions both const
, then the 2 functions will have no differences except for the return type which is not a legal override. So the former one is not designed to be const
though it can be const
.
Thanks!
Think about the issue that a ref at (size_type n) const;
could cause. First of all, you need to understand why const_reference at (size_type n) const;
exists. In a const std::vector
, once it is initialized, it or its elements are not supposed to be changed (because it is, after all, const
). The normal reference at (size_type n);
will not work for a const
vector, because it returns a non-const
reference to an element, meaning it can be changed. This goes against the idea of const
ing your object, which is why this specific overload would not work for a const
vector.
This is where const_reference at (size_type n) const;
comes in. As you may know, the end const
is a promise to the compiler and the programmer that this will not change its object or provide the opportunity for its object to be changed, so it can be used with a const
object. In the case of const_reference at (size_type n) const;
, this is indeed true: it returns a const
reference, meaning the element you get cannot be changed. This guarantees that your const
vector is indeed const
and it will not be changed.
This is why reference at (size_type n) const;
is a problem. You're lying to both the compiler and the programmer by saying that this is safe to use on a const
object, where in fact it is indeed not, because since it returns a mutable reference, you can easily change the element you get with at
.
Just ask yourself: wouldn't you be shocked if this program worked?
#include <vector>
int main()
{
const std::vector<int> a = {1, 2, 3};
a.at(0) = 10;
}