This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++20 status.

### 3131. `addressof` all the things

Section: 27.13 [time.parse], 21.3.3.8.1 [string.accessors], 21.4.3 [string.view.template], 22.2.1 [container.requirements.general], 23.3.5.4 [output.iterators], 23.3.5.6 [bidirectional.iterators], 30.6 [re.traits], 30.11.1 [re.regiter], 32.5.5.2 [thread.lock.guard] Status: C++20 Submitter: Tim Song Opened: 2018-06-30 Last modified: 2021-02-25

Priority: 0

View all other issues in [time.parse].

View all issues with C++20 status.

Discussion:

Some additional instances where the library specification applies unary operator `&` when it should use `addressof`.

[2018-07-20 Status to Tentatively Ready after five positive votes on the reflector.]

[2018-11, Adopted in San Diego]

Proposed resolution:

This wording is relative to N4750.

> [Drafting note: Two uses of `&` in 23.5.1 [reverse.iterators] are not included in the wording below because the entire sentence is slated to be removed by a revision of P0896, the One Ranges Proposal.]

1. Change 27.13 [time.parse] p4-5 as indicated:

   >     template<class charT, class traits, class Alloc, class Parsable>
   >       unspecified
   >         parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp,
   >               basic_string<charT, traits, Alloc>& abbrev);

   > > -4- Remarks: This function shall not participate in overload resolution unless

   > > >     from_stream(declval<basic_istream<charT, traits>&>(), fmt.c_str(), tp, &addressof(abbrev))

   > > is a valid expression.

   > > -5- Returns: A manipulator that, when extracted from a `basic_istream<charT, traits> is`, calls `from_stream(is, fmt.c_str(), tp, &addressof(abbrev))`.

2. Change 27.13 [time.parse] p8-9 as indicated:

   >     template<class charT, class traits, class Alloc, class Parsable>
   >       unspecified
   >         parse(const basic_string<charT, traits, Alloc>& fmt, Parsable& tp,
   >               basic_string<charT, traits, Alloc>& abbrev, minutes& offset);

   > > -8- Remarks: This function shall not participate in overload resolution unless

   > > >     from_stream(declval<basic_istream<charT, traits>&>(), fmt.c_str(), tp, &addressof(abbrev), &offset)

   > > is a valid expression.

   > > -9- Returns: A manipulator that, when extracted from a `basic_istream<charT, traits> is`, calls `from_stream(is, fmt.c_str(), tp, &addressof(abbrev), &offset)`.

3. Change 21.3.3.8.1 [string.accessors] p1 and p4 as indicated:

   >     const charT* c_str() const noexcept;
   >     const charT* data() const noexcept;

   > > -1- Returns: A pointer `p` such that `p + i == &addressof(operator[](i))` for each `i` in `[0, size()]`.

   > > -2- Complexity: Constant time.

   > > -3- Requires: The program shall not alter any of the values stored in the character array.

   >     charT* data() noexcept;

   > > -4- Returns: A pointer `p` such that `p + i == &addressof(operator[](i))` for each `i` in `[0, size()]`.

   > > -5- Complexity: Constant time.

   > > -6- Requires: The program shall not alter the value stored at `p + size()`.

4. Change 21.4.3.3 [string.view.iterators] p4 as indicated:

   >     constexpr const_iterator begin() const noexcept;
   >     constexpr const_iterator cbegin() const noexcept;

   > > -4- Returns: An iterator such that

   > > (4.1) — if `!empty()`, `&addressof(*begin()) == data_`,

   > > (4.2) — otherwise, an unspecified value such that `[begin(), end())` is a valid range.

5. Change 21.4.3.7 [string.view.ops] p21 and p24 as indicated:

   >     constexpr bool starts_with(charT x) const noexcept;

   > > -21- Effects: Equivalent to: `return starts_with(basic_string_view(&addressof(x), 1));`

   > […]

   >     constexpr bool ends_with(charT x) const noexcept;

   > > -24- Effects: Equivalent to: `return ends_with(basic_string_view(&addressof(x), 1));`

6. Change 21.4.3.8 [string.view.find] p5 as indicated:

   > -5- Each member function of the form

   > >     constexpr return-type F(charT c, size_type pos);

   > is equivalent to `return F(basic_string_view(&addressof(c), 1), pos);`

7. Edit 22.2.1 [container.requirements.general], Table 77 — "Container requirements", as indicated:

   > Table 77 — Container requirements
   > Expression | Return type | Operational semantics | Assertion/note pre/post-condition | Complexity
   > --- | --- | --- | --- | ---
   > `[…]`
   > `(&a)->a.~X()` | `void` |  | the destructor is applied to every element of `a`; any memory obtained is deallocated. | linear
   > `[…]`

8. Edit 23.3.5.4 [output.iterators], Table 90 — "Output iterator requirements (in addition to Iterator)", as indicated:

   > Table 90 — Output iterator requirements (in addition to Iterator)
   > Expression | Return type | Operational semantics | Assertion/note pre/post-condition
   > --- | --- | --- | ---
   > `[…]`
   > `++r` | `X&` |  | `&addressof(r) == &addressof(++r)`. […]
   > `[…]`

9. Edit 23.3.5.6 [bidirectional.iterators], Table 92 — "Bidirectional iterator requirements (in addition to forward iterator)", as indicated:

   > Table 92 — Bidirectional iterator requirements (in addition to forward iterator)
   > Expression | Return type | Operational semantics | Assertion/note pre/post-condition
   > --- | --- | --- | ---
   > `--r` | `X&` |  | […] `&addressof(r) == &addressof(--r)`.
   > `[…]`

10. Change 30.6 [re.traits] p6 as indicated:

    >     template<class ForwardIterator>
    >       string_type transform(ForwardIterator first, ForwardIterator last) const;

    > > -6- Effects: As if by:

    > > >     string_type str(first, last);
    > > >     return use_facet<collate<charT>>(
    > > >       getloc()).transform(&*str.begindata(), &*str.begindata() + str.length());

11. Change 30.11.1.2 [re.regiter.cnstr] p2 as indicated:

    >     regex_iterator(BidirectionalIterator a, BidirectionalIterator b,
    >                    const regex_type& re,
    >                    regex_constants::match_flag_type m = regex_constants::match_default);

    > > -2- Effects: Initializes `begin` and `end` to `a` and `b`, respectively, sets `pregex` to `&addressof(re)`, sets `flags` to `m`, then calls `regex_search(begin, end, match, *pregex, flags)`. If this call returns `false` the constructor sets `*this` to the end-of-sequence iterator.

12. Change 30.11.1.4 [re.regiter.deref] p2 as indicated:

    >     const value_type* operator->() const;

    > > -2- Returns: `&addressof(match)`.

13. Change 32.5.5.2 [thread.lock.guard] p2-7 as indicated:

    >     explicit lock_guard(mutex_type& m);

    > > -2- Requires: If `mutex_type` is not a recursive mutex, the calling thread does not own the mutex `m`.

    > > -3- Effects: As if by Initializes `pm` with `m`. Calls `m.lock()`.

    > > -4- Postconditions: `&pm == &m`

    >     lock_guard(mutex_type& m, adopt_lock_t);

    > > -5- Requires: The calling thread owns the mutex `m`.

    > > -6- Postconditions: `&pm == &m` Effects: Initializes `pm` with `m`.

    > > -7- Throws: Nothing.