Преобразование комментария в ответ:
В этом подходе нет ничего неправильного; доступ к члену класса соответствует аналогичному правилу (E1.E2
является значением xvalue, если E1
является rvalue, а E2
- нестатическим членом данных и не является ссылкой, см. [expr.ref] /4.2) и элементами внутри контейнера логически похожи на нестатические члены данных.
Существенной проблемой при выполнении этого для std::vector
или других стандартных контейнеров является то, что он, вероятно, сломает некоторый старый код. Рассмотрим:
void foo(int &);
std::vector<int> bar();
foo(bar()[0]);
. Последняя строка прекратит компиляцию, если operator[]
в векторе rvalue возвратил значение x. Альтернативно - и, возможно, хуже - если есть перегрузка foo(const int &)
, он будет беззвучно запускать эту функцию вместо этого.
Также, возвращая кучу элементов в контейнере и используя только один элемент, уже довольно неэффективно , Можно утверждать, что код, который делает это, вероятно, все равно не заботится о скорости, и поэтому небольшое улучшение производительности не стоит вводить потенциально разрушающие изменения.
Я думаю, что вы оставите контейнер в недопустимом состоянии, если вы выйдете из одного из элементов, я бы сказал, что нужно разрешить это состояние вообще. Во-вторых, если вам это понадобится, не можете ли вы просто вызвать конструктор перемещения нового объекта следующим образом:
T copyObj = std::move(makeVector()[0]);
Обновление:
Самое главное опять же на мой взгляд, что контейнеры являются контейнерами по своей природе, поэтому они не должны каким-либо образом изменять элементы внутри них. Они просто предоставляют хранилище, механизм итераций и т. Д.