<html>
	<head>
		<title>N1694=04-0134, A Proposal to Extend the Function Call Operator</title>
		<meta content="http://schemas.microsoft.com/intellisense/ie5" name="vs_targetSchema">
		<meta http-equiv="Content-Language" content="en-us">
		<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
	</head>
	<body bgColor="#ffffff">
		<ADDRESS>Document number: N1694=04-0134</ADDRESS>
		<ADDRESS>Programming Language C++, Evolution Working Group</ADDRESS>
		<ADDRESS>&nbsp;</ADDRESS>
		<ADDRESS>Peter Dimov &lt;<A href="mailto:pdimov@mmltd.net">pdimov@mmltd.net</A>&gt;</ADDRESS>
		<ADDRESS>&nbsp;</ADDRESS>
		<ADDRESS>September 06, 2004</ADDRESS>
		<h1>
			A Proposal to Extend the Function Call Operator</h1>
		<h2>
			Introduction</h2>
		<p>In a function call expression of the form <code>E(a1, ..., aN)</code>, where the 
			expression <code>E</code> evaluates to an object of class type (13.3.1.1.2, 
			[over.call.object]), <code>E</code>'s conversion operators are only considered 
			if they can convert <code>E</code> to a pointer or reference to function.</p>
		<P>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 <code>E</code> to a class 
			type with <code>operator()</code> defined (a function object) need also be 
			considered in a function call expression.</P>
		<P>In addition to making C++ more regular, this change will also considerably 
			simplify the specification and improve the behavior of <code>tr1::reference_wrapper</code>.</P>
		<H2>Motivating Example: reference_wrapper</H2>
		<P>The Library Extensions Technical Report [<A href="N1660.pdf">N1660</A>] defines, 
			in 2.1 [tr.util.refwrap], a class template <code>reference_wrapper&lt;T&gt;</code>
			that is a <code>CopyConstructible</code> and <code>Assignable</code> wrapper 
			around a reference to an object of type <code>T</code>.</P>
		<P>Objects of type <code>reference_wrapper&lt;T&gt;</code> need to be usable in 
			contexts that expect a reference to an object of type <code>T</code>, so <code>reference_wrapper&lt;T&gt;</code>
			provides a conversion operator to <code>T&amp;</code>. Unfortunately, this 
			conversion operator is typically not considered in function call expressions, 
			even though it is desirable for <code>reference_wrapper</code> objects to act 
			as function objects in such expressions. For example, two other components in 
			the Technical Report, <code>tr1::function</code> and <code>tr1::bind</code>, 
			are required by their specifications to be able to "call" <code>reference_wrapper</code>s 
			around references to function objects.</P>
		<P>To get around this apparent limitation of the language, <code>reference_wrapper&lt;T&gt;</code>
			provides a family of forwarding <code>operator()</code> functions of the form</P>
		<P><code>template&lt;class T1, ..., class TN&gt; typename result_of&lt;T(T1, ..., 
				TN)&gt;::type operator()(T1 &amp; a1, ..., TN &amp; aN) const;</code></P>
		<P>that return the result of calling the stored reference with the argument list <code>a1</code>, 
			..., <code>aN</code>. This is only an approximation due to problems with 
			argument forwarding [<A href="../2002/n1385.htm">N1385</A>] and return type 
			deduction.</P>
		<P>The proposed change will eliminate these "approximate" <code>operator()</code> overloads. 
			A <code>reference_wrapper&lt;T&gt;</code> will act as a reference to <code>T</code>
			in a function call expression.</P>
		<H2>Proposed Text</H2>
		<P>Add a new paragraph after 13.3.1.1.2/1 ([over.call.object]/1):</P>
		<BLOCKQUOTE>
			<P>For each conversion function declared in <code>T</code> of the form</P>
			<BLOCKQUOTE>
				<P><code>operator <em>conversion-type-id</em> () <em>cv-qualifier</em>;</code></P>
			</BLOCKQUOTE>
			<P>where <em>cv-qualifier</em> is the same cv-qualification as, or a greater 
				cv-qualification than, <em>cv</em>, and where <em>conversion-type-id</em> denotes 
				the possibly cv-qualified class type <code>U</code>, or a reference to the 
				possibly cv-qualified class type <code>U</code>, the function call operators of <code>
					U</code> are added to the set of candidate functions.</P>
		</BLOCKQUOTE>
		<P>[Note: changes are relative to ISO/IEC 14882:2003(E).]</P>
		<H2>Impact on Existing Code</H2>
		<P>Existing code is affected in the following two situations:</P>
		<UL>
			<LI>
				<code>T</code> contains both function call operators and a conversion to a 
				function object type <code>U</code> and one of the function call operators in <code>
					U</code> is a better match than all of the function call operators in <code>T</code>. 
				The call is ambiguous because the implicit object parameter needs a 
				user-defined conversion to match <code>U</code>;
			<LI>
				<code>T</code> contains a conversion to a pointer or a reference to a function 
				and a conversion to a function object type <code>U</code>.</LI></UL>
		<P>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.</P>
		<ADDRESS>--end</ADDRESS>
	</body>
</html>
