Стандартные контейнеры С++ предлагают только одну версию operator[] для контейнеров, таких как vector<T> и deque<T>. Он возвращает T& (кроме vector<bool>, который я проигнорирую), что является lvalue. Это означает, что в коде, подобном этому,
vector<BigObject> makeVector(); // factory function
auto copyOfObject = makeVector()[0]; // copy BigObject
copyOfObject будет построена копия. Учитывая, что makeVector() возвращает rvalue vector, представляется разумным ожидать, что конструкция copyOfObject будет построена.
Если operator[] для таких контейнеров был перегружен для объектов rvalue и lvalue, то operator[] для контейнеров rvalue мог возвращать ссылку rvalue, то есть rvalue:
template<typename T>
container {
public:
T& operator[](int index) &; // for lvalue objects
T&& operator[](int index) &&; // for rvalue objects
...
};
В этом случае copyOfObject будет построено движение.
Есть ли причина, по которой такая перегрузка будет плохой идеей вообще? Есть ли причина, почему это не было сделано для стандартных контейнеров в С++ 14?