1294. Difference between callable wrapper and forwarding call wrapper unclear

Section: 23.14.3 [func.require] Status: C++11 Submitter: Jens Maurer Opened: 2009-12-21 Last modified: 2016-02-10

Priority: Not Prioritized

View all other issues in [func.require].

View all issues with C++11 status.

Discussion:

The current wording in the standard makes it hard to discriminate the difference between a "call wrapper" as defined in 23.14.2 [func.def]/5+6:

5 A call wrapper type is a type that holds a callable object and supports a call operation that forwards to that object.

6 A call wrapper is an object of a call wrapper type.

and a "forwarding call wrapper" as defined in 23.14.3 [func.require]/4:

4 [..] A forwarding call wrapper is a call wrapper that can be called with an argument list. [Note: in a typical implementation forwarding call wrappers have an overloaded function call operator of the form

template<class... ArgTypes>
R operator()(ArgTypes&&... args) cv-qual;

end note]

Reason for this lack of clear difference seems to be that the wording adaption to variadics and rvalues that were applied after it's original proposal in N1673:

[..] A forwarding call wrapper is a call wrapper that can be called with an argument list t1, t2, ..., tN where each ti is an lvalue. The effect of calling a forwarding call wrapper with one or more arguments that are rvalues is implementation defined. [Note: in a typical implementation forwarding call wrappers have overloaded function call operators of the form

template<class T1, class T2, ..., class TN>
R operator()(T1& t1, T2& t2, ..., TN& tN) cv-qual;

end note]

combined with the fact that the word "forward" has two different meanings in this context. This issue attempts to clarify the difference better.

[ 2010-09-14 Daniel provides improved wording and verified that it is correct against N3126. Previous resolution is shown here: ]

4 [..] A forwarding call wrapper is a call wrapper that can be called with an arbitrary argument list and uses perfect forwarding to deliver the arguments to the wrapped callable object. [Note: in a typical implementation forwarding call wrappers have an overloaded function call operator of the form

template<class... ArgTypes>
R operator()(ArgTypes&&... args) cv-qual;

end note]

[ Adopted at 2010-11 Batavia ]

Proposed resolution:

Change 23.14.3 [func.require]/4 as indicated:

[..] A forwarding call wrapper is a call wrapper that can be called with an arbitrary argument list and delivers the arguments as references to the wrapped callable object. This forwarding step shall ensure that rvalue arguments are delivered as rvalue-references and lvalue arguments are delivered as lvalue-references. [Note: in a typical implementation forwarding call wrappers have an overloaded function call operator of the form

template<class... UnBoundArgs>
R operator()(UnBoundArgs&&... unbound_args) cv-qual;

end note ]