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

4264. Skipping indirection is not allowed for function_ref

Section: 22.10.17.1 [func.wrap.general] Status: New Submitter: Tomasz Kamiński Opened: 2025-05-15 Last modified: 2025-05-18

Priority: Not Prioritized

View all issues with New status.

Discussion:

Currently the wording in 22.10.17.1 [func.wrap.general] allows implementation to avoid double indirection when constructing owning functions wrappers from another one:

-2- Let t be an object of a type that is a specialization of function, copyable_function, or move_only_function, such that the target object x of t has a type that is a specialization of function, copyable_function, or move_only_function. Each argument of the invocation of x evaluated as part of the invocation of t may alias an argument in the same position in the invocation of t that has the same type, even if the corresponding parameter is not of reference type.

However, the wording does not cover a function_ref, disallowing implementation to perform this optimization when signatures are compatible, for example:

std::function_ref<void() noexcept> f1(ptr);
std::function_ref<void()> f1(f2);

We should include function_ref in the list. Note that this allows, but does not require, an implementation to perform such an optimization. As a consequence, it is acceptable to specify the allowance for all combinations of polymorphic wrappers, even for creating an owning wrapper from a non-owning one, where implementing such an optimization may not be possible.

Proposed resolution:

This wording is relative to N5008.

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

    -2- Let t be an object of a type that is a specialization of function, copyable_function, or move_only_function, or function_ref, such that the target object x of t has a type that is a specialization of function, copyable_function, ormove_only_function, or function_ref. Each argument of the invocation of x evaluated as part of the invocation of t may alias an argument in the same position in the invocation of t that has the same type, even if the corresponding parameter is not of reference type.