5

Iterators from different containers cannot be compared (see for example here:https://stackoverflow.com/a/4664519/225186) (or more technically, it doesn't need to make sense.)

This raises another question, can iterator from different ranges be assigned to each other?

Container A = ...;
Container B = ...;
auto it1 = A.begin();
it1 = B.begin(); // it1 first belonged to A, does it1 need to belong to B later 

Is the last line required to work by the Iterator concept in some standard or in the accepted practices or in the upcoming std ranges?

Since equality and assigment are so intertwined, it seem that if equality (==) is not always well defined then assignment (=) doesn't need to be well defined either, and probably for similar underlying reasons.

The reason I ask is not purely academic, because a certain iterator implementation could have some "metadata" from the container, and that (depending on the implementation) may or may not be able to be reassigned or simply a waste to be reassigned. (For example a stride information that is unique to A and doesn't agree with that of B. Another example is when the iterator stores a reference to the original range.)

This could allow that when assignment is tried, a particular field (member) might be left untouched. One could make the assignment work in some cases, and that may produce less surprises, but it could also limit the implementations, and the question is would it be really necessary to define/allow the assignment between iterators of different origin (provenance)?


UPDATE 2021:

The linked documents read things like:

[...] the term the domain of == is used in the ordinary mathematical sense to denote the set of values over which == is (required to be) defined. This set can change over time. Each algorithm places additional requirements on the domain of == for the iterator values it uses. These requirements can be inferred from the uses that algorithm makes of == and !=.

So there is an implicit defined (by the algorithms) range of validity of == . Another way to formulate this question is if the same caveats for the domain of applicability of == can be applied, by simple use of logic, to =.

The underlying idea is that defining == in isolation of = or vise versa doesn't make sense. (and also because I found a motivating case).

alfC
  • 14,261
  • 4
  • 67
  • 118
  • I can't be sure of course, but a quick search over the various container and iterator requirements in the standard doesn't reveal anything about assignment. As a matter of fact, it doesn't appear like iterators *have* to be assignable at all, even if they point into the same container. – StoryTeller - Unslander Monica Jun 07 '20 at 08:27
  • @StoryTeller-UnslanderMonica [LegacyIterator](https://en.cppreference.com/w/cpp/named_req/Iterator) specifies they must be copy assignable – Alan Birtles Jun 07 '20 at 08:40
  • @AlanBirtles - Ah yes. That would do it. In the latest standard draft it's in http://eel.is/c++draft/iterators#iterator.iterators-2.1 – StoryTeller - Unslander Monica Jun 07 '20 at 08:47

1 Answers1

1

If you check out cppreference.com for the container you are interested you can find out the requirements for its iterators.

If we look at std::vector for example, its iterators are specified to be LegacyRandomAccessIterator. If you follow the hierarchy of definitions up from there to the base LegacyIterator you'll see that iterators are required to be CopyAssignable which means you must be able to assign one iterator to another of the same type.

All of the standard library containers use iterators derived from LegacyIterator, containers from other libraries or containers are free to ignore these requirements but it would be quite surprising to users if iterators weren't CopyAssignable and even more surprising if iterators were only not CopyAssignable between containers of the same type as that would potentially only be a runtime failure and not a compile time failure.

Alan Birtles
  • 32,622
  • 4
  • 31
  • 60
  • Yes, the problem is that usually when you read the fine print or hear experts they usually admit that there is a (runtime) caveat next to each concept requirement that (implicitly) reads “... within the domain of validity”. So for example `sort` asks for `TotalOrder` but we happily pass `double`s to it because we “know” that the range doesn’t contain NaNs. I am wondering if it similar here. Iterators needs to be copy assignable, yes, but “within a certain domain of validity”? – alfC Jun 07 '20 at 21:54
  • 1
    The standard library iterators are all assignable, if they aren't your standard library implementation is buggy. Other libraries are free to make their iterators fail to assign at runtime but that would be a pretty poor implementation – Alan Birtles Jun 08 '20 at 06:12