Live data from Hacker News

Writing a custom iterator in modern C++

internalpointers.com

51–60 of 79 posts

Re: Writing a custom iterator in modern C++

#51
post #39

The classic iterator categories (input, output, ...) discussed in this article have been deprecated in C++20, and replaced with new concepts. I would expect a post from 2020 claiming to be about iterators "in modern C++" to be specifically about that change, but actually it's just about the legacy categories, so this is a pretty worthless article.

On the contrary, this article can be used by the audience in almost any modern C++ compiler out there. An article using C++20 will just lead to frustration, as there are still rough edges using concepts, with a standard that was just published last week.

Sure, this is the technique that you want to use for programs that you write today. But given that it's using the iterator concepts that have existed for decades, that will be deprecated soon if not now, why claim it's "modern C++"? The only thing I could see in the whole article that wouldn't work in C++98 was range-based for loops. At least they didn't use std::iterator, which was deprecated in C++17.

The title is misleading marketing: It gives the impression you need this nice new blog post instead of all the old out of date ones, and that it's all you'll need to know for the foreseeable future.

Re: Writing a custom iterator in modern C++

#52

Earlier quoted context omitted.

Any kind of generator is basically like this. Imagine one for listing the contents of a directory... maybe it looks like this: class DirectoryChildren { void *dir; void *buffer; size_t buffer_size; size_t buffer_offset; ... public: bool next(FileInfo *info); }; Bear in mind the buffer only represents a chunk of intermediate results fetched from the OS; when we reach its end, we have to request more data from the OS.…

This functionality already exists in the C++ standard library as std::filesystem::(recursive_)directory_iterator with the default constructor creating a sentinel value. This is solution (1) and this is due to the restriction that prior to C++20 iterators were required to be the same type. C++20 relaxes this restriction and allows the sentinel to be any type as long as it is equality comparable with the other iterator…

Why do you keep repeating the same comment? Are you reading my replies? I already addressed exactly what you're talking about: https://news.ycombinator.com/item?id=25492756

Re: Writing a custom iterator in modern C++

#53
post #39

Earlier quoted context omitted.

On the contrary, this article can be used by the audience in almost any modern C++ compiler out there. An article using C++20 will just lead to frustration, as there are still rough edges using concepts, with a standard that was just published last week.

Sure, this is the technique that you want to use for programs that you write today. But given that it's using the iterator concepts that have existed for decades, that will be deprecated soon if not now, why claim it's "modern C++"? The only thing I could see in the whole article that wouldn't work in C++98 was range-based for loops. At least they didn't use std::iterator, which was deprecated in C++17. The title is…

Well, regarding "modern C++", I have seen that moniker applied to even language features that were already available in pre-ISO C++98, like RAII, or type safe collections.

Apparently too many people still keep using C++ compilers to compile C code, not surprising when there are schools still using Turbo C++ for MS-DOS as teaching tool, as per one of Bjarne talks.

Back to C++20, C++ is no longer my main tool, but I still follow up on it and one of my hobbies is checking new standard features, hardly everything works at is supposed to be and I expect the usual three years for stabilization, so when C++23 will be around the corner, is when I expect all major compilers to fully support C++20 without triggering some kind of compiler error.

Re: Writing a custom iterator in modern C++

#54
post #49

Iterators are a very powerful concept, however, it is very cumbersome and often impossible, to implement some interesting iterator based on the standard iterators. This stems from the idea that any iterator can based on a single pointer and use pointer comparison for indicating the start and the end of the contents. The most common case, are forward output iterators, for which I usually define a class that defines th…

An iterator is a class. It can contain any private data you desire and mutate in any wonderful and/or stupid ways you desire.

How it decides to compare equal to the .end() instance is also your call. Your example is not a compliant iterator (as in, wouldn't work in a range-based for loop) - yet the same behaviour would be achievable through your own operator++() and operator bool(),

Re: Writing a custom iterator in modern C++

#55

Earlier quoted context omitted.

You can think of it as implementing `seek`, not just `next`. `RandomAccessIterator` implements the `+=` and `-=` operations that `BidirectionalIterator` does not. Algorithms that accept `RandomAccessIterator` can then assume that calling += is possible.

What's the advantage to using a random access iterator over a get() indexed? Like to me the point of an iterator is that it abstracts over access kind, and exposes the minimum viable view, which is sequential forward and possibly backward access. If you want indexed access why wouldn't you just, you know, use anything that implements operator[]?

[] alone doesn't imply that the view is sequential. Binary search for example requires both sequential items and indexed access. You can't binary search an std::map even if it implements [].

Re: Writing a custom iterator in modern C++

#56

The classic iterator categories (input, output, ...) discussed in this article have been deprecated in C++20, and replaced with new concepts. I would expect a post from 2020 claiming to be about iterators "in modern C++" to be specifically about that change, but actually it's just about the legacy categories, so this is a pretty worthless article.

[deleted]

Re: Writing a custom iterator in modern C++

#57
post #54
post #49

Iterators are a very powerful concept, however, it is very cumbersome and often impossible, to implement some interesting iterator based on the standard iterators. This stems from the idea that any iterator can based on a single pointer and use pointer comparison for indicating the start and the end of the contents. The most common case, are forward output iterators, for which I usually define a class that defines th…

An iterator is a class. It can contain any private data you desire and mutate in any wonderful and/or stupid ways you desire. How it decides to compare equal to the .end() instance is also your call. Your example is not a compliant iterator (as in, wouldn't work in a range-based for loop) - yet the same behaviour would be achievable through your own operator++() and operator bool(),

I agree, but I feel it is a little sad that such a powerful programming concept as an iterator is hard to implement in C++ if you want to make full use of it. Other program languages have made better choices with respect to this and allow you to write cleaner, shorter code.

Re: Writing a custom iterator in modern C++

#58

Earlier quoted context omitted.

You can think of it as implementing `seek`, not just `next`. `RandomAccessIterator` implements the `+=` and `-=` operations that `BidirectionalIterator` does not. Algorithms that accept `RandomAccessIterator` can then assume that calling += is possible.

What's the advantage to using a random access iterator over a get() indexed? Like to me the point of an iterator is that it abstracts over access kind, and exposes the minimum viable view, which is sequential forward and possibly backward access. If you want indexed access why wouldn't you just, you know, use anything that implements operator[]?

You need an additional API to create views/sublists if you want to transparently operate on sub ranges and if you want to return a found index you may need to convert its value to apply to a parent view.

Re: Writing a custom iterator in modern C++

#59
post #53

Earlier quoted context omitted.

Sure, this is the technique that you want to use for programs that you write today. But given that it's using the iterator concepts that have existed for decades, that will be deprecated soon if not now, why claim it's "modern C++"? The only thing I could see in the whole article that wouldn't work in C++98 was range-based for loops. At least they didn't use std::iterator, which was deprecated in C++17. The title is…

Well, regarding "modern C++", I have seen that moniker applied to even language features that were already available in pre-ISO C++98, like RAII, or type safe collections. Apparently too many people still keep using C++ compilers to compile C code, not surprising when there are schools still using Turbo C++ for MS-DOS as teaching tool, as per one of Bjarne talks. Back to C++20, C++ is no longer my main tool, but I st…

> regarding "modern C++", I have seen that moniker applied to even language features that were already available in pre-ISO C++98, like RAII, or type safe collections.

That's not surprising as modern C++ predates C++11. Newer standards "merely" make it more convenient to practice it.

At the end of the day, modern c++ is really about emphasizing value types, RAII and parametric polymorphism as opposed to OOP.

Anyway, these days we have it good conformance to new standards comes relatively quickly. It took forever for most compilers to be C+98 conformant (and technically most never reached it).

Re: Writing a custom iterator in modern C++

#60
post #43

Earlier quoted context omitted.

It isn't a sentinel is it? He said no runtime data, so it sounds like some kind of empty tag for the type system. I'm not sure if it is related to what he is describing, but C++20 also added [[no_unique_address]] for something to do with truly empty members.

Distinguishing two members of a union with... 0 bytes of extra data? Sounds like magic. Not 100% sure about the terminology. Pick whatever word might fit it better. I just called it a sentinel.

Why would you need a union?
Post reply on HN