I'd have expected that if an std::array
is an rvalue, then calling operator[]
returns an rvalue as well. But it doesn't seem to be the case (cppreference), there are no value-category overloads.
For example, std::optional
respects the value category (cppreference). Why don't we have the same overloads in std::array
, like this?
const T &&operator[](size_type pos) const &&
const T &operator[](size_type pos) const &
T &&operator[](size_type pos) &&
T &operator[](size_type pos) &
(of course, this question is not just about operator[]
, but all the other accessor functions)
Here's is an example which shows that in this regard, std::array
is not a drop-in replacement for old-style arrays. With old-style arrays, the result of the index operator is an rvalue reference, but with std::array
, it is not:
#include <array>
#include <utility>
#include <type_traits>
#include <cstdio>
int main() {
int old_way[1];
std::array<int, 1> new_way;
printf("old_way, is_rvalue_reference: %d\n", std::is_rvalue_reference_v<decltype(std::move(old_way)[0])>);
printf("new_way, is_rvalue_reference: %d\n", std::is_rvalue_reference_v<decltype(std::move(new_way)[0])>);
}
This program prints:
old_way, is_rvalue_reference: 1
new_way, is_rvalue_reference: 0
It behaves consistently with other (sequence) containers. The (sequence) container concept requires the type to have member typedefs reference
and const_reference
which shall be returned by operator[]
depending on const
-qualification. But there is no equivalent distinction made for lvalue and rvalue references to elements.
Containers have existed before C++11 when the reference qualifiers for member functions were introduced. So they were not able to forward value category originally. And because of a lack of move semantics it wouldn't have been very helpful at that time either.
Also, std::array
was originally part of TR1 and derived from boost::array
, both before C++11. At the time the necessary syntax didn't exist yet either.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With