Live data from Hacker News

Writing a custom iterator in modern C++

internalpointers.com

71–79 of 79 posts

Re: Writing a custom iterator in modern C++

#72
post #57
post #54

Earlier quoted context omitted.

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.

Why not just use those two operators instead of more and next?

Re: Writing a custom iterator in modern C++

#73
post #69
post #68

Earlier quoted context omitted.

Code size is not always a good performance metric

Nothing is a good performance metric apart from profiling. Preferably with runtime conditions (CPU load, memory bandwidth, etc.) closely mirroring production setting(s). It's very easy to forget things like memory bandwidth, inter-core/CPU links, etc. are all limited resources. And that on real systems resources are shared.

I usually profile everything with valgrind callgrind

Re: Writing a custom iterator in modern C++

#74

Earlier quoted context omitted.

Honest question: what does it mean for something to be "deprecated" in (specifically) the c++ language spec?

The spec itself defines it as: Normative for the current edition of the Standard, but having been identified as a candidate for removal from future revisions This is a very blunt tool. In practice, a feature may be deprecated if it is: 1. Legacy inherited from C that serves no modern purpose. The register keyword. 2. Features hardly anybody implemented. Exported templates is the only example I am aware of. Like falli…

strstream was adopted into C++98 with conflicting implementations, so was deprecated at the outset. You are warned not to use the conflicting parts in code meant to be portable.

strstream has not been removed, yet, because spanstream is not in yet. Until that is in, there are certain things only strstream can do: specifically, attach to an existing buffer you need to parse things out of, or to format things into.

Re: Writing a custom iterator in modern C++

#75
post #60

Earlier quoted context omitted.

Why would you need a union?

Write me some code that shows me how to compose iterator-based ranges with just 1 iterator's worth of space in each range.

It is not so clear to me what you mean. Maybe you can point to a better version (maybe what some other language does), and I can explain how I think the same can be done with C++20 ranges. I believe ranges are strictly more powerful than what other languages provide, and often they can be slimmer/more efficient for the common case.

Re: Writing a custom iterator in modern C++

#76
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.

I thought he was saying the `end` in range begin/end was now allowed to be some empty signifier to tell things to look for the null pointer (null is a sentinel, but `end` itself is now empty). That may not be right, I don't know enough about the new concepts stuff and range seems to be part of that.

edit: looking at this it maybe covers it:

https://foonathan.net/2020/03/iterator-sentinel/

Re: Writing a custom iterator in modern C++

#77
post #76

Earlier quoted context omitted.

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.

I thought he was saying the `end` in range begin/end was now allowed to be some empty signifier to tell things to look for the null pointer (null is a sentinel, but `end` itself is now empty). That may not be right, I don't know enough about the new concepts stuff and range seems to be part of that. edit: looking at this it maybe covers it: https://foonathan.net/2020/03/iterator-sentinel/

Yes but I'm saying this is kind of moot when you're writing a struct that needs to store the iterators, because it can't get away with just storing the 'begin' -- you can't guarantee the second iterator you're storing will actually be the end. Meaning this iteration model isn't efficiently composable.

Re: Writing a custom iterator in modern C++

#78
post #67

Earlier quoted context omitted.

Usually people say std::sort is faster than qsort

It's true whenever the function call overhead for the comparison operation dominates. Inlining a trivial operation (often just one instruction) is one extreme. At the other extreme L1C cache (typically just 32 kB) gets constantly trashed by numerous type specialized functions. Individually fast when microbenchmarked, but collectively slow. That's why profiling is a must when high performance is required. Microbenchma…

Why would all template specializations for be in L1?

Even assuming you actually have multiple specializations in the same binary, which is not a given, only the one being in use or that it will be used very soon will be in L1. Instruction cache prefetching is extremely effective.

Re: Writing a custom iterator in modern C++

#79

Earlier quoted context omitted.

I think you are arguing that iterators are "primarily" for iteration. But in C++ they really are like an abstraction over C pointers. For example, you can hold a std::list::iterator, and use it to efficiently delete from a linked list, without ever iterating. Sometimes C pointers are used for iteration, but I would not say that is their primary purpose.

> I think you are arguing that iterators are "primarily" for iteration I really wonder why people put up with something named this way then. "That fool thinks iterators are for iteration !" Clarity of abstraction and good naming are important, unless the practitioners are masochists.

Cursor would be a better name probably, but I wouldn't say the name is misleading, as iteration is an important use case.
Post reply on HN