r-значение ref-определителей для контейнеров STL
Почему элемент обращается к функциям-членам контейнеров STL, например std::array::operator[]
или же std::vector::operator[]
у вас нет перегрузок refvalififier rvalue? Конечно я могу сделать std::move(generate_vector()[10])
, но мне любопытно, рассматривалось ли добавление перегрузок refvalififier rvalue при стандартизации ref-квалификаторов.
Я думаю std::array<T, N>
а также std::tuple<T, T, ..., T>
действительно одно и то же, и функция доступа к элементу (т.е. std::get
)"последнего перегружается для всех комбинаций const против non-const и lvalue против rvalue. Почему не первый?
Является ли хорошей идеей добавить в мой пользовательский контейнер функции доступа к элементам с квалификацией rvalue (которые возвращают ссылки на rvalue)?
РЕДАКТИРОВАТЬ
На комментарий Ричарда Криттена. Я думаю, что это может быть иногда полезно.
Например, у вас есть функция, которая возвращает контейнер, созданный внутри этой функции, но вас может заинтересовать только первый элемент этого контейнера. Да, это глупо. В этом случае определенно лучше использовать более простую функцию, которая создает только первый элемент. Но если функция не ваша, у вас нет такого выбора.
Или, может быть, есть более общие примеры. У вас есть функция, которая создает контейнер, и вы хотите обработать этот контейнер, чтобы получить другой результат. Например, вы можете выполнить std::reduce
, или же std::unique_copy
в этот контейнер. (Кажется, что запрещено изменять элементы во время выполнения std::reduce
, но давайте просто предположим, что мы реализовали нашу собственную, которая позволяет модификации.) В этом случае можно использовать std::make_move_iterator
, но почему бы не позволить самому контейнеру возвращать итераторы перемещения?
EDIT2
Фактически, я столкнулся с этой проблемой, когда я реализую некоторые классы "представления" в классе контейнера. Изменяемое представление (ссылка на lvalue), неизменяемое представление (ссылка на const) и подвижное представление (ссылка на rvalue) кажутся необходимыми, и мне нужно определить, что следует возвращать из функций-членов доступа к элементу класса подвижного представления: ссылки на lvalue или rvalue? Мне было немного странно возвращать rvalue ссылки на элементы, где сам контейнер не предоставляет такие интерфейсы. Который правильный?
- lvalue ссылки.
- Rvalue ссылки.
- Подвижный вид, в общем-то, не правильный. Такое не нужно часто, и в моем дизайне должны быть серьезные проблемы.
1 ответ
Нет особой проблемы с добавлением ref-квалификаторов ко всему, что возвращает ссылки, однако это в основном удваивает число членов, что, как правило, будет иметь идентичные реализации, кроме переноса возврата в std::move
,
class A
{
int a;
int& operator[](std::size_t pos) & { return a; }
int&& operator[](std::size_t pos) && { return std::move(a); }
};
Стандартная библиотека отказалась предоставлять эти перегрузки, так же, как она отказалась предоставить много volatile
Перегрузки. В этом случае вы можете просто std::move
&
значение, где вам это нужно.
Если вы пишете свои собственные контейнеры, то нет причин, чтобы избежать таких перегрузок. Это увеличивает нагрузку на обслуживание, поэтому я бы посоветовал против этого.