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