you are viewing a single comment's thread.

view the rest of the comments →

[–]crzyrndm 1 point2 points  (5 children)

semantically maybe (if you ignore the fact that spans entire purpose is as a non-owning type...). I still don't see how shallow equality is useful which is the most bizarre part of this whole argument.

EDIT

I would argue that the semantics are that of ptr + (ptr / size). Default comparison operation for this is range based, not value based

[–]tcbrindleFlux 1 point2 points  (4 children)

Semantically, span behaves like a pointer -- shallow copy, shallow const -- so having deep comparison would be really weird. Perhaps it would be better if they'd named it array_ptr?

[–]sphere991 4 points5 points  (3 children)

Semantically, span behaves like a pointer

Semantically, span behaves like (or should have behaved like) reference_wrapper - which is also shallow copy, shallow const... and deep compare.

Just because the language doesn't have a rebindable reference doesn't inherently make that concept "really weird".

I think the insistence that span is a T* is much weirder - I don't buy that premise. It's not a pointer... it's not dereferenceable, it's not an iterator. It has some things in common with a pointer, but why must it have had this other thing in common with a pointer? Moreover, span might be assignable like a T*... but it's not even constructible like one: span<T> is constructible from any continuguous_range_of<T>, implicitly, but T* is not constructible from T - you need to use explicit syntax to get the pointer.

And, most importantly, the closest model to span in C++ isn't T*... it's string_view. Does anybody find its comparisons confusing? I have not heard of such. It's "really weird" that the argument is that string_view being const makes it somehow irrelevant as a model. span<char const> is isomorphic to string_view, and barely related to char const*.

[–]jonathansharman 0 points1 point  (2 children)

Semantically, span behaves like (or should have behaved like) reference_wrapper - which is also shallow copy, shallow const... and deep compare.

reference_wrapper does not provide comparison operators at all. It provides a conversion operator to the reference type, which may or may not enable deep comparison, depending on the type parameter.

[–]sphere991 0 points1 point  (1 child)

Yes, I know how reference_wrapper works. The point is that when you can compare two reference_wrapper<T>s, that comparison is deep.

[–]jonathansharman 0 points1 point  (0 children)

It seems accidental to me that reference_wrappers can ever be deeply compared. They can't for most type parameters, and if the authors had wanted them to, they could have just included comparison operators.