Title
bind() should be const-overloaded, not cv-overloaded
Status
c++17
Section
[func.bind.bind]
Submitter
Stephan T. Lavavej

Created on 2015-03-27.00:00:00 last changed 90 months ago

Messages

Date: 2015-05-07.23:01:40

Proposed resolution:

This wording is relative to N4296.

  1. Change [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.

    […]

Date: 2015-05-07.23:01:40

[ 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

Date: 2015-03-27.00:00:00

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.)

History
Date User Action Args
2017-07-30 20:15:43adminsetstatus: wp -> c++17
2015-10-27 16:52:45adminsetstatus: ready -> wp
2015-05-07 23:01:40adminsetmessages: + msg7393
2015-05-07 23:01:40adminsetstatus: new -> ready
2015-04-03 16:21:41adminsetmessages: + msg7319
2015-03-27 00:00:00admincreate