Title
`move_only_function` constructor should recognize empty `copyable_function`s
Status
new
Section
[func.wrap.move.ctor]
Submitter
Tomasz Kamiński

Created on 2025-05-12.00:00:00 last changed 3 weeks ago

Messages

Date: 2025-05-12.11:00:33

Proposed resolution:

This wording is relative to N5008.

  1. Modify [func.wrap.general] as indicated:

    template<class F> move_only_function(F&& f);
    
    […]

    -8- Postconditions:: *this has no target object if any of the following hold:

    1. (8.1) — f is a null function pointer value, or

    2. (8.2) — f is a null member pointer value, or

    3. (8.2) — remove_cvref_t<F> is a specialization of the move_only_function or copyable_function class template, and f has no target object.

Date: 2025-05-18.08:49:08

The standard currently requires that constructing move_only_function from empty copyable_function, creates an non-empty move_only_function, that contains an empty copyable_function as the target. For example:

std::copyable_function<int(int)> ce;
std::move_only_function<int(int)> me(ce);

We require that invoking me(1) is undefined behavior (as it leads to call to the ce(1)), however it cannot be detected in the user code, as me != nullptr is true.

We should require the move_only_function(F&& f) constructor to create an empty object, if f is an instantiation of copyable_function and f == nullptr is true, i.e. `f` does not contain target object.

This simplifies implementing avoidance of double wrapping per [func.wrap.general] p2, as transferring the target produces an empty functor.

The copyable_function cannot be constructed from move_only_function, as it requires functor to be copyable. Invoking an empty std::function has well defined behavior (throws bad_function_call), and wrapping such object into other functors should reproduce that behavior.

History
Date User Action Args
2025-05-12 11:00:33adminsetmessages: + msg14748
2025-05-12 00:00:00admincreate