Reputation: 7717
Wasn't the std::span
designed as a lightweight reference to sub-regions of std::vector
/std::array
/plain array and alike? Shouldn't it also contain comparison operators in its API, to be consistent with them? What was the reasoning behind the exclusion?
Note: by comparison operators, I mean either the full set (<
, <=
, ...) or the spaceship <=>
Upvotes: 25
Views: 5244
Reputation: 13040
As Daniel Langr pointed out, std::span
has comparison operators in its initial proposal P0122. These operators are then removed since the working draft N4791, and the reasons are stated in P1085.
In short, copy and const for std::span
are "shallow" (meaning copying a std::span
doesn't copy its underlying elements, and a const std::span
doesn't prevent its underlying elements from being modified), so comparisons, if exist, should also be "shallow" for consistency.
That paper gives the following examples:
Example 1:
T oldx = x;
change(x);
assert(oldx != x);
return oldx;
Example 2:
void read_only(const T & x);
void f()
{
T tmp = x;
read_only(x);
assert(tmp == x);
}
The assertions in these examples may fail if T = std::span
, while it doesn't for regular types.
One may argue that std::string_view
has shallow copy but deep comparisons. P1085 also has an explanation for this:
This matches
string_view
, howeverstring_view
can't modify the elements it points at, and thus the shallow copy ofstring_view
can be thought of as similar to a copy-on-write optimization.
Upvotes: 13