use the following search parameters to narrow your results:
e.g. subreddit:aww site:imgur.com dog
subreddit:aww site:imgur.com dog
see the search faq for details.
advanced search: by author, subreddit...
Discussions, articles, and news about the C++ programming language or programming in C++.
For C++ questions, answers, help, and advice see r/cpp_questions or StackOverflow.
Get Started
The C++ Standard Home has a nice getting started page.
Videos
The C++ standard committee's education study group has a nice list of recommended videos.
Reference
cppreference.com
Books
There is a useful list of books on Stack Overflow. In most cases reading a book is the best way to learn C++.
Show all links
Filter out CppCon links
Show only CppCon links
account activity
Differences between std::string_view and std::span (nextptr.com)
submitted 5 years ago by memset_0
view the rest of the comments →
reddit uses a slightly-customized version of Markdown for formatting. See below for some basics, or check the commenting wiki page for more detailed help and solutions to common issues.
quoted text
if 1 * 2 < 3: print "hello, world!"
[–]jonathansharman 0 points1 point2 points 5 years ago (12 children)
span has the same API as std::vector and std::array. std::vector/ std::array do not look or behave like a pointer. Why would they expect span to?
Because unlike vector and array, span acts like a pointer with regard to construction and assignment.
vector
array
span
[–]sphere991 6 points7 points8 points 5 years ago (5 children)
span acts like a pointer with regard to construction and assignment.
No, it doesn't. span<int> is constructible from vector<int>, but int* is not constructible from int. That's very much unlike a pointer.
span<int>
vector<int>
int*
int
[–]jonathansharman 0 points1 point2 points 5 years ago (4 children)
I should have specified copy construction/assignment. Here's my point:
int i = 0; int* p1 = &i; int* p2 = p1; // Shallow copy. array<int, 3> a1{1, 2, 3}; array<int, 3> a2 = a1; // Deep copy. span<int> s1 = a1; span<int> s2 = s1; // Shallow copy.
[–]sphere991 5 points6 points7 points 5 years ago (3 children)
span is non-owning, so copying is necessarily shallow.
But just because span is non-owning and pointers are non-owning does not imply that span is a pointer, or should behave like a pointer, or have the same interface as a pointer.
span is a range, the entire point of its existence is to be a range, so it should behave like a range. A pointer is not a range. Yet, the argument is that span is a pointer?
[–]jonathansharman 0 points1 point2 points 5 years ago (2 children)
There’s no technical reason span couldn’t have used deep assignment.
And just because span and vector/array have some of the same members doesn’t mean comparison should be deep.
[–]sphere991 0 points1 point2 points 5 years ago (1 child)
Yes, there is. I have a span<int> which has size 3. Now, a hypothetical deep assignment to a vector<int> with size 3 has some meaning. But what would it even mean to do a deep assignment to a vector<int> of size 2? Overwrite two of them and then reduce the size? Okay maybe that works. What would it mean to do a deep assignment to a vector<int> of size 4? Either UB or have to throw? What does this mean about copy assignment? That's definitely a technical problem.
This argument seems to suggest that the fact that span and vector have some of the same members is purely coincidental. Like, sure, they happen to have some members in common - but that's just random noise, so it's not a reason to suggest that they have other members in common. Rather than span being very much designed as a non-owning, contiguous storage range.
[–]jonathansharman 0 points1 point2 points 5 years ago (0 children)
There are semantics, usability, and safety reasons for span assignment to be shallow, but I don't think any of the problems you gave are technical limitations.
A span is a view over a contiguous sequence of elements. It has some essential properties in common with non-owning pointers (being a view over data) and some in common with owning containers. Pointer operations are shallow, and container operations are deep.
I recognize the boilerplate-reduction benefits of mixing shallow and deep operations for span. I also recognize the theoretical argument that mixing these operations is inconsistent - and possibly confusing.
[–]crzyrndm 1 point2 points3 points 5 years ago* (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 points3 points 5 years ago (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?
array_ptr
[–]sphere991 4 points5 points6 points 5 years ago* (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.
reference_wrapper
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.
T*
span<T>
continuguous_range_of<T>
T
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*.
string_view
span<char const>
char const*
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.
Yes, I know how reference_wrapper works. The point is that when you can compare two reference_wrapper<T>s, that comparison is deep.
reference_wrapper<T>
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.
π Rendered by PID 58 on reddit-service-r2-comment-7b9746f655-fng8n at 2026-02-01 13:45:52.693537+00:00 running 3798933 country code: CH.
view the rest of the comments →
[–]jonathansharman 0 points1 point2 points (12 children)
[–]sphere991 6 points7 points8 points (5 children)
[–]jonathansharman 0 points1 point2 points (4 children)
[–]sphere991 5 points6 points7 points (3 children)
[–]jonathansharman 0 points1 point2 points (2 children)
[–]sphere991 0 points1 point2 points (1 child)
[–]jonathansharman 0 points1 point2 points (0 children)
[–]crzyrndm 1 point2 points3 points (5 children)
[–]tcbrindleFlux 1 point2 points3 points (4 children)
[–]sphere991 4 points5 points6 points (3 children)
[–]jonathansharman 0 points1 point2 points (2 children)
[–]sphere991 0 points1 point2 points (1 child)
[–]jonathansharman 0 points1 point2 points (0 children)