Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[iterator.requirements.general] Allowed operations on singular iterators needs rephrasing #2381

Open
jwakely opened this issue Nov 6, 2018 · 1 comment

Comments

@jwakely
Copy link
Member

jwakely commented Nov 6, 2018

We have a sentence that tries to enumerate all the things allowed on singular iterators. For the last clause in the sentence it's unclear which operand is the singular iterator that is the subject of the sentence. Worse, the next sentence (after the note) says "In these cases the singular value is overwritten" which is completely untrue for 2/3 of "these cases".

Maybe split it into bullets (changes to existing wording highlighted in bold):

Results of most expressions are undefined for singular values; except for the following cases:

  • Destruction of an iterator that holds a singular value.

  • Assignment of a non-singular value to an iterator that holds a singular value, in which case the singular value is overwritten the same way as any other value.

  • For iterators that satisfy the Cpp17DefaultConstructible requirements, using a value-initialized singular iterator as the source of a copy or move operation. [Note: This
    guarantee is not offered for default-initialization, although the distinction only matters for types with trivial
    default constructors such as pointers or aggregates holding pointers. — end note]

Dereferenceable values are always non-singular.

For the third bullet, we only need to define what happens for value-initialized iterators that also happen to be singular, because otherwise we don't need to make an exception for them here. There could be a type where a value-initialized iterator is not singular (it might refer to some global sequence by default).

Regarding the note, is it true that "the distinction only matters for types with trivial
default constructors such as pointers or aggregates holding pointers"? What matters for [dcl.init] is whether the constructor is user-provided, not trivial. For example:

struct Iter {
    std::string unused;
    int* ptr;
    int& operator*() { return *ptr; }
    // ...
};

This has a non-trivial default constructor, but the distinction between default-initialization and value-initialization matters.

@CaseyCarter
Copy link
Contributor

CaseyCarter commented Nov 6, 2018

[Note: This guarantee is not offered for default-initialization, although the distinction only matters for types with trivial default constructors such as pointers or aggregates holding pointers. — end note]

Nitpick: There's no guarantee that default-initialization is equivalent to value-initialization for a type with non-trivial default-initialization (for example).

Regarding the note, is it true that "the distinction only matters for types with trivial default constructors such as pointers or aggregates holding pointers"?

Oops - I see you've already noticed this as well. Consider my first comment as corroboration.

@jensmaurer jensmaurer changed the title Allowed operations on singular iterators needs rephrasing [iterator.requirements.general] Allowed operations on singular iterators needs rephrasing Nov 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants