Почему элемент обращается к функциям-членам контейнеров 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
, но почему бы не позволить самому контейнеру возвращать итераторы перемещения?
Фактически, я столкнулся с этой проблемой, когда я реализую некоторые классы «представления» в классе контейнера. Изменяемое представление (ссылка на lvalue), неизменяемое представление (ссылка на const) и подвижное представление (ссылка на rvalue) кажутся необходимыми, и мне нужно определить, что следует возвращать из функций-членов доступа к элементу класса подвижного представления: ссылки на lvalue или rvalue ? Мне было немного странно возвращать rvalue ссылки на элементы, где сам контейнер не предоставляет такие интерфейсы. Который правильный?
Нет особой проблемы с добавлением 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
&
значение, где вам это нужно.
Если вы пишете свои собственные контейнеры, то нет безопасность причина избегать таких перегрузок. Это увеличивает бремя обслуживания, так что я бы советовал против этого.
Других решений пока нет …