`<functional>`: Avoid double wrapping in `move_only_function` construction
Nobody has claimed this yet.
- 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].
- Let
tbe an object of a type that is a specialization offunction,copyable_function, ormove_only_function, such that the target objectxofthas a type that is a specialization offunction,copyable_function, ormove_only_function. Each argument of the invocation ofxevaluated as part of the invocation oftmay alias an argument in the same position in the invocation oftthat 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]
- 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_functionfrom an emptyfunction, we need to keep the throwing-on-invocation behavior, which means that the constructedmove_only_functioncan'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
functionis already broken, and the program-defined specializations can hardly be helpful, it might be also plausible not to do this.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- 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