Revised 2013-01-15 at 16:01:04 UTC

## Tentative Issues

### 2078. Throw specification of `async()` incomplete

Section: 30.6.8 [futures.async] Status: Tentatively NAD Editorial Submitter: Nicolai Josuttis Opened: 2011-08-29 Last modified: 2012-11-14

View other active issues in [futures.async].

View all other issues in [futures.async].

View all issues with Tentatively NAD Editorial status.

Discussion:

The current throw specification of `async()` does state:

> -6- Throws: `system_error` if policy is `launch::async` and the implementation is unable to start a new thread.

First it seems not clear whether this only applies if policy equals `launch::async` of if the `async` launch mode flag is set (if `policy|launch::async!=0`)

In the discussion Lawrence Crowl also wrote:

> More generally, I think what we want to say is that if the implementation cannot successfully execute on one of the policies allowed, then it must choose another. The principle would apply to implementation-defined policies as well.

Peter Sommerlad:

> Should not throw. That was the intent. "is async" meat exactly.

[2012, Portland: move to Tentatively NAD Editorial]

If no launch policy, it is undefined behavior.

Agree with Lawrence, should try all the allowed policies. We will rephrase so that the policy argument should be `lauch::async`. Current wording seems good enough.

We believe this choice of policy statement is really an editorial issue.

Proposed resolution:

### 2080. Specify when `once_flag` becomes invalid

Section: 30.4.4 [thread.once] Status: Tentatively Ready Submitter: Nicolai Josuttis Opened: 2011-08-30 Last modified: 2012-11-14

View all issues with Tentatively Ready status.

Discussion:

In function `call_once` 30.4.4.2 [thread.once.callonce] paragraph 4 and 5 specify for `call_once()`:

> Throws: `system_error` when an exception is required (30.2.2 [thread.req.exception]), or any exception thrown by `func`.

> Error conditions:
> - `invalid_argument` — if the `once_flag` object is no longer valid.

However, nowhere in 30.4.4 [thread.once] is specified, when a once-flag becomes invalid.

As far as I know this happens if the flag is used for different functions. So we either have to have to insert a sentence/paragraph in

> 30.4.4.2 Function call_once [thread.once.callonce]

or

> 30.4.4 Call once [thread.once]

explaining when a `once_flag` becomes invalidated or we should state as error condition something like:

- `invalid_argument` — if the `func` used in combination with the `once_flag` is different from a previously passed `func` for the same `once_flag`

Anthony Williams:

> A `once_flag` is invalidated if you destroy it (e.g. it is an automatic object, or heap allocated and deleted, etc.)

> If the library can detect that this is the case then it will throw this exception. If it cannot detect such a case then it will never be thrown.

Jonathan Wakely:

> I have also wondered how that error can happen in C++, where the type system will reject a non-callable type being passed to `call_once()` and should prevent a `once_flag` being used after its destructor runs.

> If a `once_flag` is used after its destructor runs then it is indeed undefined behaviour, so implementations are already free to throw any exception (or set fire to a printer) without the standard saying so.

> My assumption was that it's an artefact of basing the API on pthreads, which says:

> > The `pthread_once()` function may fail if:

> > `[EINVAL]` If either `once_control` or `init_routine` is invalid.

Pete Becker:

> Yes, probably. We had to clean up several UNIXisms that were in the original design.

[2012, Kona]

Remove error conditions, move to Review.

[2012, Portland: move to Tentatively Ready]

Concurrency move to Ready, pending LWG review.

LWG did not have time to perform the final review in Portland, so moving to tentatively ready to reflect the Concurrency belief that the issue is ready, but could use a final inspection from library wordsmiths.

Proposed resolution:

This wording is relative to N3337.

1. Change 30.4.4.2 [thread.once.callonce] as indicated:

   >     template<class Callable, class ...Args>
   >     void call_once(once_flag& flag, Callable&& func, Args&&... args);

   > > […]

   > > -4- Throws: `system_error` when an exception is required (30.2.2), or any exception thrown by `func`.

   > > -5- Error conditions:
   > > - `invalid_argument` — if the `once_flag` object is no longer valid.

### 2109. Incorrect requirements for `hash` specializations

Section: 19.5.5 [syserr.hash], 20.7.2.6 [util.smartptr.hash], 20.8.12 [unord.hash], 20.13.1 [type.index.synopsis], 21.6 [basic.string.hash], 23.3.7 [vector.bool], 30.3.1.1 [thread.thread.id] Status: Tentatively Ready Submitter: Daniel Krügler Opened: 2011-12-04 Last modified: 2012-11-14

View all issues with Tentatively Ready status.

Discussion:

20.7.2.6 [util.smartptr.hash] p2 is specified as follows:

> Requires: the template specializations shall meet the requirements of class template `hash` (20.8.12).

The problem here is the usage of a Requires element, which is actually a pre-condition that a user of a component has to satisfy. But the intent of this wording is actually to be a requirement on implementations. The Requires element should be removed here and the wording should be improved to say what it was intended for.

We have similar situations in basically all other places where the specification of library-provided `hash` specializations is defined. Usually, the Requires element is incorrect. In the special case of `hash<unique_ptr<T, D>>` the implementation depends on the behaviour of `hash` specializations, that could be user-provided. In this case the specification needs to separate the requirements on these specializations and those that are imposed on the implementation.

[2012, Kona]

Update wording and move to Review.

Believe a simpler formulation is to simply string the term Requires: and leave the current wording intact, rather than strike the whole clause and replace it.

[Originally proposed wording for reference

1. Change 19.5.5 [syserr.hash] as indicated:

   >     template <> struct hash<error_code>;

   > > -1- Requires: the template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<system_error>` provides a definition for a specialization of the template `hash<error_code>`. The requirements for the members of this specialization are given in sub-clause 20.8.12 [unord.hash].

2. Change 20.5.3 [bitset.hash] as indicated:

   >     template <size_t N> struct hash<bitset<N> >;

   > > -1- Requires: the template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<bitset>` provides a definition for a partial specialization of the `hash` class template for specializations of class template `bitset<N>`. The requirements for the members of instantiations of this specialization are given in sub-clause 20.8.12 [unord.hash].

3. Change 20.7.2.6 [util.smartptr.hash] as indicated:

   >     template <class T, class D> struct hash<unique_ptr<T, D> >;

   > > -1- Requires: the template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<memory>` provides a definition for a partial specialization of the `hash` class template for specializations of class template `unique_ptr<T, D>`. The requirements for the members of instantiations of this specialization are given in sub-clause 20.8.12 [unord.hash]. For an object `p` of type `UP`, where `UP` is `unique_ptr<T, D>`, `hash<UP>()(p)` shall evaluate to the same value as `hash<typename UP::pointer>()(p.get())`. The specialization `hash<typename UP::pointer>` shall be well-formed.

   > > -?- Requires: The specialization `hash<typename UP::pointer>` shall be well-formed and well-defined [Note: the general requirements of class template `hash` (20.8.12 [unord.hash]) are implied — end note].

   >     template <class T> struct hash<shared_ptr<T> >;

   > > -2- Requires: the template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<memory>` provides a definition for a partial specialization of the `hash` class template for specializations of class template `shared_ptr<T>`. The requirements for the members of instantiations of this specialization are given in sub-clause 20.8.12 [unord.hash]. For an object `p` of type `shared_ptr<T>`, `hash<shared_ptr<T> >()(p)` shall evaluate to the same value as `hash<T*>()(p.get())`.

4. Change 20.8.12 [unord.hash] p2 as indicated: [Comment: For unknown reasons the extended integer types are not mentioned here, which looks like an oversight to me and makes also the wording more complicated. See 2119 for this part of the problem. — end comment]

   >     template <> struct hash<bool>;
   >     template <> struct hash<char>;
   >     […]
   >     template <> struct hash<long double>;
   >     template <class T> struct hash<T*>;

   > > -2- Requires: the template specializations shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<functional>` provides definitions for specializations of the `hash` class template for each cv-unqualified arithmetic type except for the extended integer types. This header also provides a definition for a partial specialization of the `hash` class template for any pointer type. The requirements for the members of these specializations are given in sub-clause 20.8.12 [unord.hash].

5. Change 20.13.4 [type.index.hash] p1 as indicated:

   >     template <> struct hash<type_index>;

   > > -1- Requires: the template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<typeindex>` provides a definition for a specialization of the template `hash<type_index>`. The requirements for the members of this specialization are given in sub-clause 20.8.12 [unord.hash]. For an object `index` of type `type_index`, `hash<type_index>()(index)` shall evaluate to the same result as `index.hash_code()`.

6. Change 21.6 [basic.string.hash] p1 as indicated:

   >     template <> struct hash<string>;
   >     template <> struct hash<u16string>;
   >     template <> struct hash<u32string>;
   >     template <> struct hash<wstring>;

   > > -1- Requires: the template specializations shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<string>` provides definitions for specializations of the `hash` class template for the types `string`, `u16string`, `u32string`, and `wstring`. The requirements for the members of these specializations are given in sub-clause 20.8.12 [unord.hash].

7. Change 23.3.7 [vector.bool] p7 as indicated:

   >     template <class Allocator> struct hash<vector<bool, Allocator> >;

   > > -7- Requires: the template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<vector>` provides a definition for a partial specialization of the `hash` class template for specializations of class template `vector<bool, Allocator>`. The requirements for the members of instantiations of this specialization are given in sub-clause 20.8.12 [unord.hash].

8. Change 30.3.1.1 [thread.thread.id] p14 as indicated:

   >     template <> struct hash<thread::id>;

   > > -14- Requires: the template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash])The header `<thread>` provides a definition for a specialization of the template `hash<thread::id>`. The requirements for the members of this specialization are given in sub-clause 20.8.12 [unord.hash].

]

[2012, Portland: Move to Tentatively Ready]

No further wording issues, so move to Tentatively Ready (post meeting issues processing).

Proposed resolution:

1. Change 19.5.5 [syserr.hash] as indicated:

   >     template <> struct hash<error_code>;

   > > -1- Requires: t The template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash].

2. Change 20.5.3 [bitset.hash] as indicated:

   >     template <size_t N> struct hash<bitset<N> >;

   > > -1- Requires: t The template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash]).

3. Change 20.7.2.6 [util.smartptr.hash] as indicated:

   >     template <class T, class D> struct hash<unique_ptr<T, D> >;

   > > -1- Requires: t The template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash]). For an object `p` of type `UP`, where `UP` is `unique_ptr<T, D>`, `hash<UP>()(p)` shall evaluate to the same value as `hash<typename UP::pointer>()(p.get())`. The specialization `hash<typename UP::pointer>` shall be well-formed.

   > > -?- Requires: The specialization `hash<typename UP::pointer>` shall be well-formed and well-defined, and shall meet the requirements of class template `hash` (20.8.12 [unord.hash]).

   >     template <class T> struct hash<shared_ptr<T> >;

   > > -2- Requires: t The template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash]). For an object `p` of type `shared_ptr<T>`, `hash<shared_ptr<T> >()(p)` shall evaluate to the same value as `hash<T*>()(p.get())`.

4. Change 20.8.12 [unord.hash] p2 as indicated: [Comment: For unknown reasons the extended integer types are not mentioned here, which looks like an oversight to me and makes also the wording more complicated. See 2119 for this part of the problem. — end comment]

   >     template <> struct hash<bool>;
   >     template <> struct hash<char>;
   >     […]
   >     template <> struct hash<long double>;
   >     template <class T> struct hash<T*>;

   > > -2- Requires: t The template specializations shall meet the requirements of class template `hash` (20.8.12 [unord.hash]).

5. Change 20.13.4 [type.index.hash] p1 as indicated:

   >     template <> struct hash<type_index>;

   > > -1- Requires: t The template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash]). For an object `index` of type `type_index`, `hash<type_index>()(index)` shall evaluate to the same result as `index.hash_code()`.

6. Change 21.6 [basic.string.hash] p1 as indicated:

   >     template <> struct hash<string>;
   >     template <> struct hash<u16string>;
   >     template <> struct hash<u32string>;
   >     template <> struct hash<wstring>;

   > > -1- Requires: t The template specializations shall meet the requirements of class template `hash` (20.8.12 [unord.hash]).

7. Change 23.3.7 [vector.bool] p7 as indicated:

   >     template <class Allocator> struct hash<vector<bool, Allocator> >;

   > > -7- Requires: t The template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash]).

8. Change 30.3.1.1 [thread.thread.id] p14 as indicated:

   >     template <> struct hash<thread::id>;

   > > -14- Requires: t The template specialization shall meet the requirements of class template `hash` (20.8.12 [unord.hash]).

### 2125. `TimedMutex` specification problem

Section: 30.4.1.3 [thread.timedmutex.requirements], 30.4.1.3.1 [thread.timedmutex.class] Status: Tentatively NAD Editorial Submitter: Vicente J. Botet Escriba Opened: 2012-01-01 Last modified: 2012-11-14

View other active issues in [thread.timedmutex.requirements].

View all other issues in [thread.timedmutex.requirements].

View all issues with Tentatively NAD Editorial status.

Discussion:

30.4.1.3.1 [thread.timedmutex.class] says:

> The class `timed_mutex` shall satisfy all of the `TimedMutex` requirements (30.4.1.3 [thread.timedmutex.requirements]). It shall be a standardlayout class (Clause 9 [class]).

Problem here is that 30.4.1.3 [thread.timedmutex.requirements] does not define a requirement set named "`TimedMutex`", it only refers to "timed mutex types"

[See also issue 2126]

[2012, Portland: move to Tentatively NAD Editorial]

We have timed mutex type, but it is labeled timed mutex requirements

We can make a suggestion, but will send to the editor as it seems purely editorial. There is a typo, and we don't have the timed mutex but 30.4.1.3 [thread.timedmutex.requirements] already says timed mutex type, and we need to reuse that term down in the class to fulfil the mutex requirement.

[To Editor:]

Replace this one with timed mutex type.

Proposed resolution:

### 2126. Several specification problems in regard to mutex requirements

Section: 30.4.1 [thread.mutex.requirements], 30.4.1.2.1 [thread.mutex.class], 30.4.1.2 [thread.mutex.requirements.mutex], 30.4.1.2.2 [thread.mutex.recursive], 30.4.1.3 [thread.timedmutex.requirements], 30.4.1.3.1 [thread.timedmutex.class], 30.4.1.3.2 [thread.timedmutex.recursive] Status: Tentatively NAD Editorial Submitter: Pete Becker Opened: 2012-01-16 Last modified: 2012-11-14

View all other issues in [thread.mutex.requirements].

View all issues with Tentatively NAD Editorial status.

Discussion:

30.4.1.2.1 [thread.mutex.class]/3 says that the class mutex "shall satisfy all the `Mutex` requirements (30.4.1 [thread.mutex.requirements])". 30.4.1.2.1 [thread.mutex.class] is part of 30.4.1 [thread.mutex.requirements], so at the very least, this requirement is recursive. But worse, there is nothing that says what "the `Mutex` requirements" refers to. For example, the "`Lockable` requirements" section starts with "A type `L` meets the `Lockable` requirements if …". There is no such statement for "the `Mutex` requirements".

Organizationally, paragraphs 1-26 in 30.4.1.2 [thread.mutex.requirements.mutex] should probably be in a subclause with a name. (This is actually an ISO requirement, to avoid exactly this kind of ambiguous referencing) Then the first sentence of 30.4.1.2.1 [thread.mutex.class]/3 can become a note: "The class mutex meets the requirements of (whatever)", since that subclause already says that the mutex types "shall meet the requirements set out in this section."

And similarly for 30.4.1.2.2 [thread.mutex.recursive]/2 (`recursive_mutex`).

30.4.1.3 [thread.timedmutex.requirements], Timed mutex types, also needs the same rearrangement: its introductory requirements should be moved into a subclause, and the first sentences of 30.4.1.3.1 [thread.timedmutex.class]/2 and 30.4.1.3.2 [thread.timedmutex.recursive]/2 should be turned into notes that refer to this new subclause and to the new subclause in 30.4.1.2 [thread.mutex.requirements.mutex].

[See also issue 2125]

[2012, Portland: move to Tentatively NAD Editorial]

Seems no real ambiguity. May need some reorg of text rather then changing the wording.

Is there much that needs to be changed? But Pete's suggestion of putting requirement in separate sub section is good. Should be the direction to editor.

Suggest this is an editorial change. Happy with Pete's comments.

Proposed resolution:

### 2134. Redundant Mutex requirement?

Section: 30.4.1.2 [thread.mutex.requirements.mutex] Status: Tentatively NAD Editorial Submitter: Pete Becker Opened: 2012-03-05 Last modified: 2012-11-14

View all other issues in [thread.mutex.requirements.mutex].

View all issues with Tentatively NAD Editorial status.

Discussion:

30.4.1.2 [thread.mutex.requirements.mutex]/11 says that prior unlock operations synchronize with `m.lock()`.

30.4.1.2 [thread.mutex.requirements.mutex]/19 says that if `m.try_lock()` succeeds, prior unlock operations synchronize with the operation.

30.4.1.2 [thread.mutex.requirements.mutex]/25 says that `m.unlock()` synchronizes with subsequent successful lock operations.

Does the third requirement add anything to the first two? If not, it should probably be a non-normative note.

[2012, Portland: move to Tentatively NAD Editorial]

Agree that third note should be non-normative and adds nothing.

Seems An Editorial change, but does changing a normative to non-normative wording makes it a non-editorial change?

Ask the editor. If not editorial, then we will agree on the fix as removal of the third point, then we will put it in ready state for Bristol.

Proposed resolution:

### 2167. Copy assignment requirements of Containers

Section: 23.2.1 [container.requirements.general] Status: Tentatively NAD Submitter: Dean Michael Berris Opened: 2012-07-13 Last modified: 2012-11-14

View other active issues in [container.requirements.general].

View all other issues in [container.requirements.general].

Discussion:

Table 96 defines the general requirement for copy assignment (row 23, page 704) as:

Table 96 — Container requirements
Expression | Return type | Operational semantics | Assertion/note pre-/post-condition | Complexity
--- | --- | --- | --- | ---
`r = a` | `X&` | `` | post: `r == a.` | linear

However there is no requirement that `T` is `CopyInsertable` into `X`.

[2012, Portland: Move to Tentatively NAD]

Howard notes that this may be a difficult requirement for `std::array`

We already have this requirement for allocator aware containers, and `std::array` already adds the appropriate extra requirement.

We say the necessary things in the necessary places, but the container requirements continue to cause confusion in where we sometimes say things. Consensus is that this issue remains NAD though.

Proposed resolution:

This wording is relative to N3376.

1. Change Table 96 — "Container requirements" in 23.2.1 [container.requirements.general]:

   Table 96 — Container requirements
   Expression | Return type | Operational semantics | Assertion/note pre-/post-condition | Complexity
   --- | --- | --- | --- | ---
   `r = a` | `X&` | `` | Requires: `T` is `CopyInsertable` into `X`. post: `r == a.` | linear

### 2177. Requirements on `Copy/MoveInsertable`

Section: 23.2.1 [container.requirements.general] Status: Tentatively Ready Submitter: Loïc Joly Opened: 2012-08-10 Last modified: 2012-11-14

View other active issues in [container.requirements.general].

View all other issues in [container.requirements.general].

View all issues with Tentatively Ready status.

Discussion:

See also discussion following c++std-lib-32883 and c++std-lib-32897.

The requirements on `CopyInsertable` and `MoveInsertable` are either incomplete, or complete but hard to figure out.

From e-mail c++std-lib-32897:

Pablo Halpern:

I agree that we need semantic requirements for all of the `*Insertable` concepts analogous to the requirements we have on similar concepts.

Howard Hinnant:

I've come to believe that the standard is actually correct as written in this area. But it is really hard to read. I would have no objection whatsoever to clarifications to `CopyInsertable` as you suggest (such as the post-conditions on `v`). And I do agree with you that the correct approach to the clarifications is to confirm that `CopyInsertable` implies `MoveInsertable`.

[2012, Portland: Move to Tentatively Ready]

Move to Tentatively Ready by unanimous consent.

Proposed resolution:

This wording is relative to N3376.

1. Edit 23.2.1 [container.requirements.general] p13 as indicated:

   > -13- […] Given a container type `X` having an `allocator_type` identical to `A` and a `value_type` identical to `T` and given an lvalue `m` of type `A`, a pointer `p` of type `T*`, an expression `v` of type (possibly `const`) `T`, and an rvalue `rv` of type `T`, the following terms are defined. If `X` is not allocator-aware, the terms below are defined as if `A` were `std::allocator<T>` — no allocator object needs to be created and user specializations of `std::allocator<T>` are not instantiated:

   > - `T` is `DefaultInsertable` into `X` means that the following expression is well-formed:

   >   >     allocator_traits<A>::construct(m, p);

   > - An element of `X` is default-inserted if it is initialized by evaluation of the expression

   >   >     allocator_traits<A>::construct(m, p);

   >   where `p` is the address of the uninitialized storage for the element allocated within `X`.

   > - `T` is `CopyMoveInsertable` into `X` means that the following expression is well-formed:

   >   >     allocator_traits<A>::construct(m, p, rv);

   >   and when evaluated the following postconditions hold: The value of `*p` is equivalent to the value of `rv` before the evaluation. [Note: `rv` remains a valid object. Its state is unspecified — end note]

   > - `T` is `MoveCopyInsertable` into `X` means that, in addition to satisfying the `MoveInsertable` requirements, the following expression is well-formed:

   >   >     allocator_traits<A>::construct(m, p, rv);

   >   and when evaluated the following postconditions hold: The value of `v` is unchanged and is equivalent to `*p`.

   > - `T` is `EmplaceConstructible` into `X` from `args`, for zero or more arguments `args`, means that the following expression is well-formed:

   >   >     allocator_traits<A>::construct(m, p, args);

   > - `T` is `Erasable` from `X` means that the following expression is well-formed:

   >   >     allocator_traits<A>::destroy(m, p);

   > [Note: A container calls `allocator_traits<A>::construct(m, p, args)` to construct an element at `p` using `args`. The default construct in `std::allocator` will call `::new((void*)p) T(args)`, but specialized allocators may choose a different definition. — end note]

### 2187. `vector<bool>` is missing `emplace` and `emplace_back` member functions

Section: 23.3.7 [vector.bool] Status: Tentatively Ready Submitter: Nevin Liber Opened: 2012-09-21 Last modified: 2012-11-14

View all other issues in [vector.bool].

View all issues with Tentatively Ready status.

Discussion:

It should have them so that it more closely matches the `vector<T>` interface, as this helps when writing generic code.

[2012, Portland: Move to Tentatively Ready]

Question on whether the variadic template is really needed, but it turns out to be needed to support `emplace` of no arguments.

Proposed resolution:

This wording is relative to N3376.

1. Change the class template `vector<bool>` synopsis, 23.3.7 [vector.bool] p1, as indicated:

   >     namespace std {
   >       template <class Allocator> class vector<bool, Allocator> {
   >       public:
   >         […]
   >         // modifiers:
   >         template <class... Args> void emplace_back(Args&&... args);
   >         void push_back(const bool& x);
   >         void pop_back();
   >         template <class... Args> iterator emplace(const_iterator position, Args&&... args);
   >         iterator insert(const_iterator position, const bool& x);
   >         […]
   >       };
   >     }