In a function call expression of the form
E(a1, ..., aN), where the
E evaluates to an object of class type (220.127.116.11.2,
E's conversion operators are only considered
if they can convert
E to a pointer or reference to function.
An important design principle of C++ is that user-defined types should be given
equal standing, wherever possible. In an application of this principle, this
paper proposes that conversion operators that convert
E to a class
operator() defined (a function object) need also be
considered in a function call expression.
In addition to making C++ more regular, this change will also considerably
simplify the specification and improve the behavior of
The Library Extensions Technical Report [N1660] defines,
in 2.1 [tr.util.refwrap], a class template
that is a
around a reference to an object of type
Objects of type
reference_wrapper<T> need to be usable in
contexts that expect a reference to an object of type
provides a conversion operator to
T&. Unfortunately, this
conversion operator is typically not considered in function call expressions,
even though it is desirable for
reference_wrapper objects to act
as function objects in such expressions. For example, two other components in
the Technical Report,
are required by their specifications to be able to "call"
around references to function objects.
To get around this apparent limitation of the language,
provides a family of forwarding
operator() functions of the form
template<class T1, ..., class TN> typename result_of<T(T1, ...,
TN)>::type operator()(T1 & a1, ..., TN & aN) const;
that return the result of calling the stored reference with the argument list
aN. This is only an approximation due to problems with
argument forwarding [N1385] and return type
The proposed change will eliminate these "approximate"
reference_wrapper<T> will act as a reference to
in a function call expression.
Add a new paragraph after 18.104.22.168.2/1 ([over.call.object]/1):
For each conversion function declared in
Tof the form
operator conversion-type-id () cv-qualifier;
where cv-qualifier is the same cv-qualification as, or a greater cv-qualification than, cv, and where conversion-type-id denotes the possibly cv-qualified class type
U, or a reference to the possibly cv-qualified class type
U, the function call operators of
Uare added to the set of candidate functions.
[Note: changes are relative to ISO/IEC 14882:2003(E).]
Existing code is affected in the following two situations:
Tcontains both function call operators and a conversion to a function object type
Uand one of the function call operators in
Uis a better match than all of the function call operators in
T. The call is ambiguous because the implicit object parameter needs a user-defined conversion to match
Tcontains a conversion to a pointer or a reference to a function and a conversion to a function object type
The general consensus in the C++ community is that conversion operators need to be avoided whenever possible. The fact that conversions to function pointers and references are considered in a function call expression comes as a surprise even to most experts. This leads the author to believe that the first situation described above is rare, and the second (which is more dangerous because it has the potential to silently alter the meaning of code) essentially nonexistent.--end