microsoft / microsoft/STL

`<functional>`: Avoid double wrapping in `move_only_function` construction

Open
#5,504 8 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

performance
Dominant language
C++
Stars
11.1k
Forks
1.7k
Avg merge
4d 15h
Merged PRs (30d)
22

Description

WG21-P2548R6 relaxed some requirements for polymorphic function wrappers by adding wording in [func.wrap.general].

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

[Example 1:

move_only_function<void(T)>
  f{copyable_function<void(T)>{[](T) {}}};
T t;
f(t);                               // it is unspecified how many copies of T are made

end example]

  1. Recommended practice: Implementations should avoid double wrapping when constructing polymorphic wrappers from one another.

However, if I understand correctly, we can't avoid double wrapping in construction of function, even in vNext, because it's target object is observable via the target member function.

For move_only_function and copyable_function, it seems possible to unwrap in construction, because the target object is not observable and thus can be non-existent under some conditions.

I think its better to treat the allowance as a DR against C++23 (i.e. to implement it for move_only_function unconditionally), because that is ABI-critical and libstdc++ starts doing so recently.

Personal concerns:

  • When constructing a move_only_function from an empty function, we need to keep the throwing-on-invocation behavior, which means that the constructed move_only_function can't be empty.
  • It might be better to recognize program-defined specializations and avoid invalid unwrapping for them. But since support for program-defined specializations of function is already broken, and the program-defined specializations can hardly be helpful, it might be also plausible not to do this.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the WG21-P2548R6 wording and tracing construction of move_only_function and copyable_function from other polymorphic wrappers. Check how an empty function is represented and how invocation behavior is preserved; done means the implementation avoids unnecessary wrapping without breaking the specified empty-wrapper behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
cpp
Domain
tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.