Topic: Functions with multiple overloads should behave like


Author: Antonio Perez <antonio@perezexcelsior.com>
Date: Tue, 15 May 2018 12:03:38 -0700 (PDT)
Raw View
------=_Part_32757_1029013735.1526411018001
Content-Type: multipart/alternative;
 boundary="----=_Part_32758_202591037.1526411018001"

------=_Part_32758_202591037.1526411018001
Content-Type: text/plain; charset="UTF-8"

*Motivation:*
Let's define a function with two overloads:
void my_print_func(int x) {
   std::cout << "My int: " << x << std::endl;
}
void my_print_func(const std::string& s) {
   std::cout << "My string: " << s << std::endl;
}

If I try passing my_print_func to a higher-order function, I get a compiler
error:

//Causes compiler error
std::invoke(my_print_func, "Hello, world");
//gcc prints "couldn't deduce template parameter _Callable"

This makes sense on face value: how does the compiler know which overload
to pass?

Here's the kicker: the compiler doesn't *need* to know which overload to
pass. Let's say I create a generic lambda that calls my print function:

auto my_print_lambda = [](auto&&... inputs) {
    return my_print_func(inputs...);
};

I can now pass my_print_lambda to a higher order function, and it'll call
the correct overload:

std::invoke(my_print_lambda, 4);
/* Output is "My int: 4" */
std::invoke(my_print_lambda, "hello, world");
/* Output is "My string: hello, world" */

*Proposal:*
When an overload can't be deduced for a function with multiple overloads,
the compiler should treat that function as though it were a generic lambda.

--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/2999e8b8-d8fe-4638-b120-f5a9581a3dad%40isocpp.org.

------=_Part_32758_202591037.1526411018001
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><b>Motivation:</b><div>Let&#39;s define a function with tw=
o overloads:</div><div><div class=3D"prettyprint" style=3D"border: 1px soli=
d rgb(187, 187, 187); word-wrap: break-word;"><code class=3D"prettyprint"><=
div class=3D"subprettyprint"><div style=3D"color: rgb(212, 212, 212); font-=
family: Menlo, Monaco, &quot;Courier New&quot;, monospace; font-size: 12px;=
 line-height: 18px; white-space: pre; background-color: rgb(255, 255, 255);=
"><div><span style=3D"color: rgb(116, 151, 145);"><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">void</span></span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> my_</span><span style=3D"color: rgb(139,=
 238, 217);"><span style=3D"color: #000;" class=3D"styled-by-prettify">prin=
t_func</span></span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">(</span><span style=3D"color: rgb(116, 151, 145);"><span style=3D"color:=
 #008;" class=3D"styled-by-prettify">int</span></span><span style=3D"color:=
 #000;" class=3D"styled-by-prettify"> x</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"styled-by=
-prettify">{</span></div><div><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> =C2=A0 =C2=A0std</span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-b=
y-prettify">cout </span><span style=3D"color: rgb(129, 198, 190);"><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span></span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: rgb(0, 255, 255);"><span style=3D"color: #080;" class=3D"styled-=
by-prettify">&quot;My int: &quot;</span></span><span style=3D"color: #000;"=
 class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(129, 198, 1=
90);"><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</s=
pan></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> x </s=
pan><span style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;"=
 class=3D"styled-by-prettify">&lt;&lt;</span></span><span style=3D"color: #=
000;" class=3D"styled-by-prettify"> std</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify">endl</span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">;</span></div><div><span style=3D"color: #660;" class=3D"sty=
led-by-prettify">}</span></div><div><span style=3D"color: rgb(116, 151, 145=
);"><span style=3D"color: #008;" class=3D"styled-by-prettify">void</span></=
span><span style=3D"color: #000;" class=3D"styled-by-prettify"> my_</span><=
span style=3D"color: rgb(139, 238, 217);"><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify">print_func</span></span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">(</span><span style=3D"color: rgb(116, 151,=
 145);"><span style=3D"color: #008;" class=3D"styled-by-prettify">const</sp=
an></span><span style=3D"color: #000;" class=3D"styled-by-prettify"> std</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><spa=
n style=3D"color: #008;" class=3D"styled-by-prettify">string</span><span st=
yle=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">&amp;</span></span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> s</span><span style=3D"color: #660;" class=3D"styled-b=
y-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">{</spa=
n></div><div><span style=3D"color: #000;" class=3D"styled-by-prettify"> =C2=
=A0 =C2=A0std</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">cout =
</span><span style=3D"color: rgb(129, 198, 190);"><span style=3D"color: #66=
0;" class=3D"styled-by-prettify">&lt;&lt;</span></span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, =
255, 255);"><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot=
;My string: &quot;</span></span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> </span><span style=3D"color: rgb(129, 198, 190);"><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">&lt;&lt;</span></span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> s </span><span style=
=3D"color: rgb(129, 198, 190);"><span style=3D"color: #660;" class=3D"style=
d-by-prettify">&lt;&lt;</span></span><span style=3D"color: #000;" class=3D"=
styled-by-prettify"> std</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify">endl</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
;</span></div><div><span style=3D"color: #660;" class=3D"styled-by-prettify=
">}</span></div></div></div></code></div><br>If I try passing my_print_func=
 to a higher-order function, I get a compiler error:</div><div><br></div><d=
iv><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187)=
; word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subpret=
typrint"><div style=3D"color: rgb(212, 212, 212); font-family: Menlo, Monac=
o, &quot;Courier New&quot;, monospace; font-size: 12px; line-height: 18px; =
white-space: pre; background-color: rgb(255, 255, 255);"><span style=3D"col=
or: rgb(139, 238, 217);"><span style=3D"color: #800;" class=3D"styled-by-pr=
ettify">//Causes compiler error</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br>std</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">::</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify">invoke</span></span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by-pretti=
fy">my_print_func</span><span style=3D"color: #660;" class=3D"styled-by-pre=
ttify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <=
/span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"color: #080;"=
 class=3D"styled-by-prettify">&quot;Hello, world&quot;</span><span style=3D=
"color: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: =
#000;" class=3D"styled-by-prettify"><br></span><span style=3D"color: #800;"=
 class=3D"styled-by-prettify">//gcc prints &quot;couldn&#39;t deduce templa=
te parameter _Callable&quot;</span></span></div></div></code></div><br>This=
 makes sense on face value: how does the compiler know which overload to pa=
ss?=C2=A0</div><div><br></div><div>Here&#39;s the kicker: the compiler does=
n&#39;t <i>need</i>=C2=A0to know which overload to pass. Let&#39;s say I cr=
eate a generic lambda that calls my print function:</div><div><br></div><di=
v><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187);=
 word-wrap: break-word;"><code class=3D"prettyprint"><div class=3D"subprett=
yprint"><div style=3D"color: rgb(212, 212, 212); font-family: Menlo, Monaco=
, &quot;Courier New&quot;, monospace; font-size: 12px; line-height: 18px; w=
hite-space: pre; background-color: rgb(255, 255, 255);"><span style=3D"colo=
r: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"styled-by-pre=
ttify">auto</span></span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> my_print_lambda </span><span style=3D"color: rgb(129, 198, 190);">=
<span style=3D"color: #660;" class=3D"styled-by-prettify">=3D</span></span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span sty=
le=3D"color: #660;" class=3D"styled-by-prettify">[](</span><span style=3D"c=
olor: rgb(116, 151, 145);"><span style=3D"color: #008;" class=3D"styled-by-=
prettify">auto</span></span><span style=3D"color: rgb(129, 198, 190);"><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">&amp;&amp;</span></sp=
an><span style=3D"color: #660;" class=3D"styled-by-prettify">...</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: rgb(255, 255, 255);"><span style=3D"color: #000;" class=3D"style=
d-by-prettify">inputs</span></span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
{</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> <br></sp=
an><span style=3D"color: rgb(139, 238, 217);"><span style=3D"color: #000;" =
class=3D"styled-by-prettify">=C2=A0 =C2=A0 </span><span style=3D"color: #00=
8;" class=3D"styled-by-prettify">return</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> my_print_func</span></span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">inputs</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">...);</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> <br></span><span style=3D"color: #660;" class=3D"s=
tyled-by-prettify">};</span></div></div></code></div><br>I can now pass my_=
print_lambda to a higher order function, and it&#39;ll call the correct ove=
rload:</div><div><br></div><div><div class=3D"prettyprint" style=3D"border:=
 1px solid rgb(187, 187, 187); word-wrap: break-word;"><code class=3D"prett=
yprint"><div class=3D"subprettyprint"><div style=3D"font-family: Menlo, Mon=
aco, &quot;Courier New&quot;, monospace; font-size: 12px; line-height: 18px=
; white-space: pre; background-color: rgb(255, 255, 255);"><div style=3D"co=
lor: rgb(212, 212, 212);"><span style=3D"color: rgb(139, 238, 217);"><span =
style=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify">invoke</span></span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify">my_print_lambda</span><span style=3D"color=
: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" =
class=3D"styled-by-prettify"> </span><span style=3D"color: rgb(0, 255, 255)=
;"><span style=3D"color: #066;" class=3D"styled-by-prettify">4</span></span=
><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify"> </span></div><div><span=
 style=3D"color: #800;" class=3D"styled-by-prettify">/</span><font color=3D=
"#000000"><span style=3D"color: #800;" class=3D"styled-by-prettify">* </spa=
n></font><span style=3D"color: #800;" class=3D"styled-by-prettify">Output i=
s &quot;My int: 4&quot; */</span></div><div style=3D"color: rgb(212, 212, 2=
12);"><span style=3D"color: rgb(139, 238, 217);"><span style=3D"color: #000=
;" class=3D"styled-by-prettify">std</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">::</span><span style=3D"color: #000;" class=3D"sty=
led-by-prettify">invoke</span></span><span style=3D"color: #660;" class=3D"=
styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"styled-by=
-prettify">my_print_lambda</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">,</span><span style=3D"color: #000;" class=3D"styled-by-pre=
ttify"> </span><span style=3D"color: rgb(0, 255, 255);"><span style=3D"colo=
r: #080;" class=3D"styled-by-prettify">&quot;hello, world&quot;</span></spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> </span></div><div styl=
e=3D"color: rgb(212, 212, 212);"><span style=3D"color: rgb(86, 108, 105);">=
<span style=3D"color: #800;" class=3D"styled-by-prettify">/* Output is &quo=
t;My string: hello,</span><span style=3D"color: #800;" class=3D"styled-by-p=
rettify"> world&quot; */</span></span></div></div></div></code></div><br><b=
>Proposal:</b></div><div>When an overload can&#39;t be deduced for a functi=
on with multiple overloads, the compiler should treat that function as thou=
gh it were a generic lambda.=C2=A0</div></div>

<p></p>

-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/2999e8b8-d8fe-4638-b120-f5a9581a3dad%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/2999e8b8-d8fe-4638-b120-f5a9581a3dad=
%40isocpp.org</a>.<br />

------=_Part_32758_202591037.1526411018001--

------=_Part_32757_1029013735.1526411018001--

.