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

### 2487. `bind()` should be `const`-overloaded, not cv-overloaded

Section: 22.10.15.4 [func.bind.bind] Status: C++17 Submitter: Stephan T. Lavavej Opened: 2015-03-27 Last modified: 2017-07-30

Priority: 2

View all other issues in [func.bind.bind].

View all issues with C++17 status.

Discussion:

The Standard currently requires `bind()` to return something with a cv-overloaded function call operator. `const` is great, but `volatile` is not. First, the Library almost always ignores `volatile`'s existence (with `<type_traits>` and `<atomic>` being rare exceptions). Second, implementations typically store bound arguments in a `tuple`, but `get()` isn't overloaded for `volatile tuple`. Third, when a bound argument is a `reference_wrapper`, we have to call `tid.get()`, but that won't compile for a `volatile reference_wrapper`. Finally, `const` and `volatile` don't always have to be handled symmetrically — for example, lambda function call operators are `const` by default, but they can't ever be `volatile`.

Implementers shouldn't be required to provide cv-overloading here. (They can provide it as a conforming extension if they want.)

[2015-05, Lenexa]

JW: why would a `reference_wrapper` be volatile?
STL: if a bound argument is a `reference_wrapper` then in a volatile-qualified operator() that member will be volatile so you can't call get() on it
STL: worded like this it's a conforming extension to kep overloading on volatile
HH: libc++ doesn't overload on volatile
JW: libstdc++ does overload for volatile
MC: move to Ready and bring motion on Friday
10 in favor, none opposed

Proposed resolution:

This wording is relative to N4296.

1. Change 22.10.15.4 [func.bind.bind] as depicted:

   >     template<class F, class... BoundArgs>
   >       unspecified bind(F&& f, BoundArgs&&... bound_args);

   > > -2- Requires: `is_constructible<FD, F>::value` shall be `true`. For each `Ti` in `BoundArgs`, `is_constructible<TiD, Ti>::value` shall be `true`. `INVOKE(fd, w1, w2, ..., wN)` (20.9.2) shall be a valid expression for some values `w1`, `w2`, ..., `wN`, where `N == sizeof...(bound_args)`. The cv-qualifiers cv of the call wrapper `g`, as specified below, shall be neither `volatile` nor `const volatile`.

   > > […]

   >     template<class R, class F, class... BoundArgs>
   >       unspecified bind(F&& f, BoundArgs&&... bound_args);

   > > -6- Requires: `is_constructible<FD, F>::value` shall be `true`. For each `Ti` in `BoundArgs`, `is_constructible<TiD, Ti>::value` shall be `true`. `INVOKE(fd, w1, w2, ..., wN)` shall be a valid expression for some values `w1`, `w2`, ..., `wN`, where `N == sizeof...(bound_args)`. The cv-qualifiers cv of the call wrapper `g`, as specified below, shall be neither `volatile` nor `const volatile`.

   > > […]