If you specialize for all the fundamental types of something like a standard container that possesses a variety of different methods, it will be very inefficient.
Therefore, the indexing operator in any case returns a reference to the object. Passing by reference is not a resource-intensive operation. Objects are not created or copied. Moreover, for fundamental types, the displacement constructor, as such, does not exist. Therefore, there is no need to specifically overload standard containers for fundamental types, which are quite a few.
In addition, we get an ambiguity with the definition of an overloaded indexing operator, since the built-in operator always returns lvalue .
There is another nuance. Even if you are not going to assign a new value to the returned object, you may still need to store pointers to these objects. For example, you may need to create an object of type std::reference_wrapper by using the function std::cref , which will point to the original object in the container. If you do not send a link to the object from the container, then you will not be able to take advantage of this opportunity.
Consider the following example.
#include <iostream> #include <functional> #include <algorithm> int main() { const std::vector<int> v = { 3, 2, 4, 5, 1 }; std::vector<std::reference_wrapper<const int>> rv = { std::cref(v[0]), std::cref(v[1]), std::cref(v[2]), std::cref(v[3]), std::cref(v[4]) }; std::sort(rv.begin(), rv.end(), [](auto &a, auto &b) { return a.get() < b.get(); }); for (int x : v) std::cout << x << ' '; std::cout << std::endl; for (const auto &r : rv) std::cout << r.get() << ' '; std::cout << std::endl; }
Output of the program to the console
3 2 4 5 1 1 2 3 4 5
In this program, declared a constant vector. However, since operator [] returns a reference to the source object, you can link it with the object std::reference_wrapper , and thus represent the elements of the source vector as ordered by different criteria.
That is, it does not matter whether the object is constant or not, however, it is often necessary to get a link to it in order to track its state. Constant objects can, among other things, also be volatile objects or have data members with the mutable modifier.
If you return an object by value from an operator, then the connection with the original object will be lost, and you will be dealing with a copy.
v[1] = 1. If returned by value, it will be bad. - KoVadimtype_traits- antonvalue_type = int, double, etc.- anton