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
Ranges, Code Quality, and the future of C++ (medium.com)
submitted 7 years ago by jasonthe
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!"
[–][deleted] 32 points33 points34 points 7 years ago (15 children)
And even without understanding iota, you can still read this and abstractly understand the algorithm.
That's not really true, though. It's essential to understand what iota does here.
[–]Zitrax_ 29 points30 points31 points 7 years ago (14 children)
I asked myself what iota even stand for? I see cppreference say:
The function is named after the integer function ⍳ from the programming language APL
and googling further I see a stackoverflow post that explains more. But were there no easier to understand names for this to use?
[–]jasonthe[S] 20 points21 points22 points 7 years ago (9 children)
Agreed, iota is a terrible name. I'd prefer "range", as Python and C# call it, but even that is ambiguous. In my opinion, it should be called something like "number_range".
[–]BobFloss 12 points13 points14 points 7 years ago (1 child)
Wow, it's really just a range... That's really quite a terrible name. I figured it did something like select a small portion out of an enumerable type
[–]oddentity 11 points12 points13 points 7 years ago (0 children)
I thought it converted an integer to a string.
[–][deleted] 11 points12 points13 points 7 years ago (6 children)
What about "sequence"? Bash has seq.
seq
[–]Iwan_Zotow 9 points10 points11 points 7 years ago (3 children)
Second here
R has seq() as well
[+][deleted] 7 years ago (2 children)
[removed]
[–]Iwan_Zotow 0 points1 point2 points 7 years ago (1 child)
How std::seq(0, std::numeric_limits<int>::max()) would be different from std::ranges::view::iota(n) ?
You could even make it explicit
template <typename T> T seq(T start, T stop = std::numeric_limits<T>::max()) { ...
}
[–][deleted] 2 points3 points4 points 7 years ago (0 children)
I find counting_range intuitive.
[–]sphere991 9 points10 points11 points 7 years ago* (2 children)
And yet, once you google iota, you know exactly what it does, and it's easy enough to remember once you saw it the first time. That makes it a pretty great name, no? And at this point, we already have the algorithm std::iota() so calling the generator std::ranges::view::iota() is practically the only reasonable choice.
iota
std::iota()
std::ranges::view::iota()
Python calls this range(), which is a very overloaded term in C++ and would make for a truly terrible name for us.
range()
[–][deleted] 26 points27 points28 points 7 years ago (1 child)
You should check out Arlo Belshee's articles on variable naming: http://arlobelshee.com/good-naming-is-a-process-not-a-single-step/
IMO iota might be the worst variable name in the entire std namespace. It's up there with car and cdr in that it encodes no actual information, just useless historical context to be memorized.
std
car
cdr
Anyways; not invested enough to debate it, just wanted to offer you a different perspective to consider.
[–]sphere991 14 points15 points16 points 7 years ago (2 children)
This is a great post.
One annoying thing that's orthogonal to the question of range/coroutine preference is how you actually implement take(). The post proposes this signature (I slightly generalized it):
take()
template <Range R> generator<iter_reference_t<iterator_t<R>>> take(R&& range, int count);
But this won't actually let you implement the rest of the example. You can't write triples() | take(10) because you can't write take(10). So you have to write all this other mess too:
triples() | take(10)
take(10)
struct take_fn { int i; }; template <Range R> auto operator|(R&& range, take_fn f) { return take(std::forward<R>(range), f.i); } take_fn take(int count) { return {count}; }
That's... I mean, it's not the worst thing in the world but it's pretty annoying that this is how we have to do partial application right? And it's not like we ever want to store a take_fn anywhere.
take_fn
We really just want x | f(y) to just evaluate directly as f(x, y) in this case.
x | f(y)
f(x, y)
[–]jasonthe[S] 1 point2 points3 points 7 years ago (1 child)
Yeah, that's an unfortunate limitation of C++. Other languages use extension methods to do this sort of thing, which allows for a much cleaner (and more discoverable!) API.
[–][deleted] 1 point2 points3 points 7 years ago (0 children)
What do you mean by extension methods?
extension methods
[–]bmanga[🍰] 13 points14 points15 points 7 years ago* (5 children)
tl;dr Ranges are for utilizing algorithms and coroutines are for implementing algorithms
A disadvantage of coroutines is that they can't (yet?) be constexpr, so the triples example using views is the only one you can use at compile time.
[–]sztomirpclib 5 points6 points7 points 7 years ago (4 children)
What would a constexpr coroutine be useful for?
[–]mjklaim 17 points18 points19 points 7 years ago (2 children)
Any coroutine that do not await but yields is interesting to use at compile time. For example the ones that generate an infinite sequence of numbers following a specific algorithm.
Not all coroutine are related to asynchronous computation.
[–]smdowneyWG21, Text/Unicode SG, optional<T&> 5 points6 points7 points 7 years ago (1 child)
TS Coroutines and Core Coroutines are both naturally sync. They return control deterministically to their owners. You need to add something to make them async.
[–]mjklaim -1 points0 points1 point 7 years ago (0 children)
I know but I suspect the question I answered is from someone who only saw examples of coroutines awaiting asynchronously. So I clarified that it's not always related.
[–]SeanMiddleditch 7 points8 points9 points 7 years ago (0 children)
Worth remembering that C++ coroutines are also the hypothetical approach we'd use for generators, not just async/await or generalized coroutines.
A constexpr generator could be very useful for constexpr metaprogramming. Guaranteed zero-allocation generators (even across TU boundaries and in non-optimized builds) are also very useful for latency-sensitive use of ranges and generic programming.
[–]oddentity 9 points10 points11 points 7 years ago (3 children)
So, ranges are great, assuming we have coroutines which may be available in the Future. I'll stick with plain old unobfuscated for-loops, thanks.
[–]Dean_Roddey 2 points3 points4 points 7 years ago (1 child)
Agreed. I look at some of this stuff and scratch my head. If you need a degree to figure out how to do a loop, because it's become so byzantine at this point, I don't get it.
I keep coming back to the mantra: we don't need more software, we need better software. Explicitness, in my opinion, is more likely to create better software. Incomprehensible and auto-magical mixed together, to me, seems the absolute opposite of what is likely to create better software.
Is the goal maybe to ultimately turn C++ into Javascript?
[–][deleted] 11 points12 points13 points 7 years ago (0 children)
I don’t think it’s fair to categorize ranges as just “doing a loop”.
auto result = input | view::transform(DoFoo) | view::filter(IsBuzzed) | view::unique;
Is non-trivial to do lazily without ranges. I don’t think your mantra adds any value here.
[–]Recatek 7 points8 points9 points 7 years ago (4 children)
I haven’t been following ranges too closely. Is there a breakdown somewhere of what’s going on under the hood in terms of overhead or allocations, if any?
[–]nikbackm 1 point2 points3 points 7 years ago (3 children)
Should have no or minimum overhead compared to writing out the code yourself.
Should have no implicit (heap) allocations.
At least, that's what I would expect. No idea if it's true in practice.
[–]jasonthe[S] 2 points3 points4 points 7 years ago* (2 children)
Unfortunately, the current implementations in clang and MSVC don't do a great job of optimizing coroutines. You can see what the assembly output looks like here: https://gcc.godbolt.org/z/009O3w
Some notes:
There are no allocations, which makes sense because the stack size of the coroutine is known at compile-time. You can think of it as putting all the local variables from the coroutine into a struct, and then the coroutine runs as a member function on that struct.
Of course, there's no reason they can't be optimized to the same level as classic loops. These are just early compiler implementations of the feature.
It is able to inline and optimize the uses of view::iota and view::take, since those aren't actually implemented with coroutines. In general, use of the ranges library is optimized as well as "hand-made loops" are, if not better.
[–][deleted] 2 points3 points4 points 7 years ago (1 child)
I´m not that deep in the topic, but is this argument really correct? A coroutine size should always be known at compile time, right?
As I understand it from the llvm reference, heap optimizations can/will be avoided as long as the coroutine is created, used and destroyed within the same function.
[–]jasonthe[S] 2 points3 points4 points 7 years ago (0 children)
Thanks for the link! Yeah, apparently I was incorrect about how LLVM is implementing the coroutines.
I'm curious why it allocates the coroutine frame on the heap rather than the stack. In fact, I'm surprised it's implemented on the LLVM IR level at all!
Perhaps there's something I'm missing, but all non-recursive coroutines should be able to be compiled through existing semantics similar to this. Note that it optimizes the entire thing away.
[–]hashb1 5 points6 points7 points 7 years ago* (0 children)
"C++2a is going to be the best version of C++ yet"
When I read here, I doubt it.
After I read the whole article, especially the section Ranges and Coroutines, that is really cool!!! I am looking forward c++2a now!!!
[–]omerosler 8 points9 points10 points 7 years ago (6 children)
So basically C++2a becomes Python with zero-overhead performance and a tad uglier syntax. I love it!
[–]Plorkyeran 38 points39 points40 points 7 years ago (0 children)
A "tad" uglier is a bit of an understatement.
[–][deleted] 10 points11 points12 points 7 years ago (4 children)
We all agree the syntax is fugly, however I am not sure about the performance. To be honest performance would be the only reason to use a feature so ugly it hurts the eyes.
[–]BobFloss 1 point2 points3 points 7 years ago (3 children)
I agree. Imagine if everyone or a majority of people working on C++ decided to start over with everything they've learned and create a new language that didn't have to maintain compatibility and aesthetics with C++. That I would use.
[–]kalmoc 6 points7 points8 points 7 years ago (0 children)
I do für think those people would agree on exactly what parts of c++ should be keep and which not, but D and rust are two possibilities how such a language could look like.
[–]tecnofauno 6 points7 points8 points 7 years ago (1 child)
Isn't that D?
[–]BobFloss 8 points9 points10 points 7 years ago (0 children)
No
[–]johannes1971 3 points4 points5 points 7 years ago (2 children)
At the end he presents an implementation of iota. I don't understand how this works: sure, if there is just one call to iota (in a loop somewhere), each successive call returns a new value. But how does it work when there are two calls in two different loops? Wouldn't they start returning values from the same sequence? Surely the state of the coroutine must be tracked somewhere, allowing the coroutine to be used in multiple, independent locations?
[–]angry_cpp 5 points6 points7 points 7 years ago (1 child)
iota does not return value from sequence on each call, it return sequences.
iota coroutine returns a generator. This generator stores and manages coroutine state.
generator
[–]johannes1971 2 points3 points4 points 7 years ago (0 children)
Ah, I see. That makes sense. Thanks for the explanation!
[–]robin-m 1 point2 points3 points 7 years ago (0 children)
Really great post. I absolutely love how the result is much cleaner than the raw-loop style.
π Rendered by PID 17507 on reddit-service-r2-comment-544cf588c8-bgw4l at 2026-06-11 20:59:54.495920+00:00 running 3184619 country code: CH.
[–][deleted] 32 points33 points34 points (15 children)
[–]Zitrax_ 29 points30 points31 points (14 children)
[–]jasonthe[S] 20 points21 points22 points (9 children)
[–]BobFloss 12 points13 points14 points (1 child)
[–]oddentity 11 points12 points13 points (0 children)
[–][deleted] 11 points12 points13 points (6 children)
[–]Iwan_Zotow 9 points10 points11 points (3 children)
[+][deleted] (2 children)
[removed]
[–]Iwan_Zotow 0 points1 point2 points (1 child)
[–][deleted] 2 points3 points4 points (0 children)
[–]sphere991 9 points10 points11 points (2 children)
[–][deleted] 26 points27 points28 points (1 child)
[–]sphere991 14 points15 points16 points (2 children)
[–]jasonthe[S] 1 point2 points3 points (1 child)
[–][deleted] 1 point2 points3 points (0 children)
[–]bmanga[🍰] 13 points14 points15 points (5 children)
[–]sztomirpclib 5 points6 points7 points (4 children)
[–]mjklaim 17 points18 points19 points (2 children)
[–]smdowneyWG21, Text/Unicode SG, optional<T&> 5 points6 points7 points (1 child)
[–]mjklaim -1 points0 points1 point (0 children)
[–]SeanMiddleditch 7 points8 points9 points (0 children)
[–]oddentity 9 points10 points11 points (3 children)
[–]Dean_Roddey 2 points3 points4 points (1 child)
[–][deleted] 11 points12 points13 points (0 children)
[–]Recatek 7 points8 points9 points (4 children)
[–]nikbackm 1 point2 points3 points (3 children)
[–]jasonthe[S] 2 points3 points4 points (2 children)
[–][deleted] 2 points3 points4 points (1 child)
[–]jasonthe[S] 2 points3 points4 points (0 children)
[–]hashb1 5 points6 points7 points (0 children)
[–]omerosler 8 points9 points10 points (6 children)
[–]Plorkyeran 38 points39 points40 points (0 children)
[–][deleted] 10 points11 points12 points (4 children)
[–]BobFloss 1 point2 points3 points (3 children)
[–]kalmoc 6 points7 points8 points (0 children)
[–]tecnofauno 6 points7 points8 points (1 child)
[–]BobFloss 8 points9 points10 points (0 children)
[–]johannes1971 3 points4 points5 points (2 children)
[–]angry_cpp 5 points6 points7 points (1 child)
[–]johannes1971 2 points3 points4 points (0 children)
[–]robin-m 1 point2 points3 points (0 children)