220 9430 <CAPBZbvwF9HjYvB6=-wxY4-m6R=7-YtjutcN0xUUHcRx1AMxTAA@mail.gmail.com> article
Path: news.gmane.org!not-for-mail
From: "Billy O'Neal" <billy.oneal@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Re: Allowing overloadable operators to be
 implemented as non-member functions
Date: Mon, 24 Feb 2014 13:45:30 -0800
Lines: 282
Approved: news@gmane.org
Message-ID: <CAPBZbvwF9HjYvB6=-wxY4-m6R=7-YtjutcN0xUUHcRx1AMxTAA@mail.gmail.com>
References: <72c8d66b-9053-455d-8af4-96191d84b0cd@isocpp.org>
 <69a7690f-632f-4ac3-ad76-b56ac59d51f1@isocpp.org> <24fcdc41-d0e1-4641-acb8-e9533ff3ac88@isocpp.org>
 <7088ca90-6da2-402c-966c-9f7838e5d05c@isocpp.org> <0e40f63d-9a5a-4f55-84a4-abb658da7537@isocpp.org>
 <514fcafa-cc2c-4887-9bcf-e44b43aadace@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary=f46d0444711d5755f004f32de666
X-Trace: ger.gmane.org 1393278362 22606 80.91.229.3 (24 Feb 2014 21:46:02 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Mon, 24 Feb 2014 21:46:02 +0000 (UTC)
Cc: myriachan@gmail.com
To: std-proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDKLBLVE6ADBBIX3V2MAKGQEBDBI6XI@isocpp.org Mon Feb 24 22:46:12 2014
Return-path: <std-proposals+bncBDKLBLVE6ADBBIX3V2MAKGQEBDBI6XI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-ie0-f199.google.com ([209.85.223.199])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDKLBLVE6ADBBIX3V2MAKGQEBDBI6XI@isocpp.org>)
	id 1WI3Lo-0000Bx-E7
	for gclcip-std-proposals@m.gmane.org; Mon, 24 Feb 2014 22:46:12 +0100
Original-Received: by mail-ie0-f199.google.com with SMTP id lx4sf29041iec.10
        for <gclcip-std-proposals@m.gmane.org>; Mon, 24 Feb 2014 13:46:11 -0800 (PST)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:mime-version:in-reply-to:references:from:date
         :message-id:subject:to:cc:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe:content-type;
        bh=bYGVxIb76Pu73JrekFBZHQz7kjueJARM2Uta9opC2DQ=;
        b=MtNaZL7Ybo97zYGiofcZoIHGKiSCt81f0utAlmg7Wv4CFuNCXOnhyi1Y8GJ1bslJ4w
         ISVX8MCqgR3Lg+KSzjKO9TS/zJbc28Wt7SNrHG0qiMTSAVlo5ZCLA5EKDlnkTeqm8tV7
         xl0ndz2RQXU9QpsRXGh61WMJlhvmQvDG3znWkR47XN0LU6TB4ynZwa8NBYeJevkawYLc
         mpMJ2O0G0cDyYbHMKBWhCwkAoSyxyPRwipT+RTr7pYE9qdgwF2TpaGjLLkr7yqrwemB6
         YTIdNU1U+d80CfzHFUUYwd4vH89VGa81mUzatrPNGWlh/zq8OejePu+mE5Ozv53o4sj3
         42hg==
X-Gm-Message-State: ALoCoQlJYrP3+NYhxLjZyxGf5MkjK3yDqmNcHGhYcggT4rA/NR1V8s20cIFDGtYQ3cyXWy9hLOXk
X-Received: by 10.182.28.36 with SMTP id y4mr9715745obg.46.1393278371331;
        Mon, 24 Feb 2014 13:46:11 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.182.181.6 with SMTP id ds6ls897503obc.77.gmail; Mon, 24 Feb
 2014 13:46:10 -0800 (PST)
X-Received: by 10.60.123.10 with SMTP id lw10mr23859080oeb.24.1393278370620;
        Mon, 24 Feb 2014 13:46:10 -0800 (PST)
Original-Received: from mail-oa0-x22c.google.com (mail-oa0-x22c.google.com [2607:f8b0:4003:c02::22c])
        by mx.google.com with ESMTPS id dq4si15399015oeb.125.2014.02.24.13.46.10
        for <std-proposals@isocpp.org>
        (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
        Mon, 24 Feb 2014 13:46:10 -0800 (PST)
Received-SPF: pass (google.com: domain of billy.oneal@gmail.com designates 2607:f8b0:4003:c02::22c as permitted sender) client-ip=2607:f8b0:4003:c02::22c;
Original-Received: by mail-oa0-f44.google.com with SMTP id m1so1943864oag.3
        for <std-proposals@isocpp.org>; Mon, 24 Feb 2014 13:46:10 -0800 (PST)
X-Received: by 10.182.233.45 with SMTP id tt13mr19877841obc.9.1393278370375;
 Mon, 24 Feb 2014 13:46:10 -0800 (PST)
Original-Received: by 10.182.87.37 with HTTP; Mon, 24 Feb 2014 13:45:30 -0800 (PST)
In-Reply-To: <514fcafa-cc2c-4887-9bcf-e44b43aadace@isocpp.org>
X-Original-Sender: billy.oneal@gmail.com
X-Original-Authentication-Results: mx.google.com;       spf=pass (google.com:
 domain of billy.oneal@gmail.com designates 2607:f8b0:4003:c02::22c as
 permitted sender) smtp.mail=billy.oneal@gmail.com;       dkim=pass
 header.i=@gmail.com;       dmarc=pass (p=NONE dis=NONE) header.from=gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:9430
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/9430>

--f46d0444711d5755f004f32de666
Content-Type: text/plain; charset=UTF-8

Even that isn't quite the way the built in operator?: works. Most notably,
it would allow the user to completely change the conversion / value
category that the normal operator?: uses. The rules under 5.16 [expr.cond]
have lots of edge cases; even places that result in the program being ill
formed as a result of type deduction against the second and third arguments.

Would you expect everyone overloading this operator to read / understand
this entire type deduction process in order to determine
ParentOfLeftAndRight above?

Finally, I note that the above program has a bug even if this were allowed,
because the result of LeftExpr or RightExpr have the temporaries to which
the references are bound only live to the end of the enclosing expression;
and optionally have their lifetime extended by being assigned to a
reference. Users expect the enclosing expression to be the one containing
the use of operator?:, not the expression inside the operator?: operator
overload. That makes code like the following undefined behavior, even
though it is perfectly well defined for the builtin ?: :

#include <iostream>
#include <string>
#include <cstdlib>

std::string Left()
{
 return "left temporary";
}

std::string Right()
{
return "right temporary";
}

// Assuming string const& operator?(string const&, string const&)

int main() {
std::string const& val = (rand() % 2 ? Left() : Right());
 std::cout << val << std::endl;
}


Billy O'Neal
https://github.com/BillyONeal/ <https://bitbucket.org/BillyONeal/>
http://stackoverflow.com/users/82320/billy-oneal


On Mon, Feb 24, 2014 at 12:53 PM, Adam Nevraumont <afn@theorem.ca> wrote:

>
>
> On Saturday, February 22, 2014 12:21:28 AM UTC-5, myri...@gmail.com wrote:
>>
>> It'd be hacky as all hell, but there is a way that overloading ?: could
>> work without losing short-circuiting or breaking the language *too*much.  I don't really know why you'd want to overload ?: in the first
>> place, but this could work:
>>
>> const ParentOfLeftAndRight &operator ?:(
>>     const Conditional &conditional,
>>     std::function<const Left &()> getLeft,
>>     std::function<const Right &>() getRight)
>> {
>>   return conditional.Evaluate() ? getLeft() : getRight();
>> }
>>
>> In other words, have the compiler generate lambdas for the expressions on
>> the left and right sides of the colon, and try to find an operator ?:
>> function that has an overload that will take that argument trio.
>>
>  Rather,
> template<typename LeftExpr, typename RightExpr>
> std::common_type_t< std::result_of_t<LeftExpr()>,
> std::result_of_t<RightExpr()> > operator?:(
>    Conditional const& condition,
>    LeftExpr&& lhs,
>    RightExpr && rhs
> )
> {
>   if (condition)
>     return std::forward<LeftExpr>(lhs)();
>   else
>     return std::forward<RightExpr>(rhs)();
> }
> where
> cond?lhs:rhs;
> is transformed into
> operator?:( cond, [&]{return lhs;}, [&]{return rhs;} )
> with maybe some verbage to make sure perfect forwarding occurs.
>
> You could naturally do the same with && and ||.  Some way (maybe something
> as hacky as the int argument to ++) to distinguish between the
> short-circuit and "traditional" overloads of && and ||.
>
> Short-circuit overloads could be preferred, or it could be ambiguous if
> both exist and are otherwise equally good.
>
> Adding a non-short-circuit ?: seems like a bad idea, for the same reason
> why nobody wants to override && and ||.  But if we first added
> short-circuit && and ||, we can add short-circuit ?: and skip the
> non-short-circuit version...
>
>
>
>
> --
>
> ---
> 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.
> Visit this group at
> http://groups.google.com/a/isocpp.org/group/std-proposals/.
>

-- 

--- 
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

--f46d0444711d5755f004f32de666
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Even that isn&#39;t quite the way the built in operator?: =
works. Most notably, it would allow the user to completely change the conve=
rsion / value category that the normal operator?: uses. The rules under 5.1=
6 [expr.cond] have lots of edge cases; even places that result in the progr=
am being ill formed as a result of type deduction against the second and th=
ird arguments.<div>

<br></div><div>Would you expect everyone overloading this operator to read =
/ understand this entire type deduction process in order to determine=C2=A0=
<span style=3D"font-family:arial,sans-serif;font-size:13px">ParentOfLeftAnd=
Right</span><span style=3D"font-family:arial,sans-serif;font-size:13px">=C2=
=A0above?</span></div>

<div><span style=3D"font-family:arial,sans-serif;font-size:13px"><br></span=
></div><div><span style=3D"font-family:arial,sans-serif;font-size:13px">Fin=
ally, I note that the above program has a bug even if this were allowed, be=
cause the result of LeftExpr or RightExpr have the temporaries to which the=
 references are bound only live to the end of the enclosing expression; and=
 optionally have their lifetime extended by being assigned to a reference. =
Users expect the enclosing expression to be the one containing the use of o=
perator?:, not the expression inside the operator?: operator overload. That=
 makes code like the following undefined behavior, even though it is perfec=
tly well defined for the builtin ?: :</span></div>

<div><span style=3D"font-family:arial,sans-serif;font-size:13px"><br></span=
></div><div><div><font face=3D"arial, sans-serif">#include &lt;iostream&gt;=
</font></div><div><font face=3D"arial, sans-serif">#include &lt;string&gt;<=
/font></div>

<div><font face=3D"arial, sans-serif">#include &lt;cstdlib&gt;</font></div>=
<div><font face=3D"arial, sans-serif"><br></font></div><div><font face=3D"a=
rial, sans-serif">std::string Left()</font></div><div><font face=3D"arial, =
sans-serif">{</font></div>

<div><font face=3D"arial, sans-serif"><span class=3D"" style=3D"white-space=
:pre">	</span>return &quot;left temporary&quot;;</font></div><div><font fac=
e=3D"arial, sans-serif">}</font></div><div><font face=3D"arial, sans-serif"=
><br>
</font></div>
<div><font face=3D"arial, sans-serif">std::string Right()</font></div><div>=
<font face=3D"arial, sans-serif">{</font></div><div><font face=3D"arial, sa=
ns-serif"><span class=3D"" style=3D"white-space:pre">	</span>return &quot;r=
ight temporary&quot;;</font></div>

<div><font face=3D"arial, sans-serif">}</font></div><div><font face=3D"aria=
l, sans-serif"><br></font></div><div><font face=3D"arial, sans-serif">// As=
suming string const&amp; operator?(string const&amp;, string const&amp;)</f=
ont></div>

<div><font face=3D"arial, sans-serif"><br></font></div><div><font face=3D"a=
rial, sans-serif">int main() {</font></div><div><font face=3D"arial, sans-s=
erif"><span class=3D"" style=3D"white-space:pre">	</span>std::string const&=
amp; val =3D (rand() % 2 ? Left() : Right());</font></div>

<div><font face=3D"arial, sans-serif"><span class=3D"" style=3D"white-space=
:pre">	</span>std::cout &lt;&lt; val &lt;&lt; std::endl;</font></div><div><=
font face=3D"arial, sans-serif">}</font></div></div><div><span style=3D"fon=
t-family:arial,sans-serif;font-size:13px"><br>

</span></div></div><div class=3D"gmail_extra"><br clear=3D"all"><div><div d=
ir=3D"ltr"><div>Billy O&#39;Neal</div><div><a href=3D"https://bitbucket.org=
/BillyONeal/" target=3D"_blank">https://github.com/BillyONeal/</a></div><di=
v><a href=3D"http://stackoverflow.com/users/82320/billy-oneal" target=3D"_b=
lank">http://stackoverflow.com/users/82320/billy-oneal</a></div>

</div></div>
<br><br><div class=3D"gmail_quote">On Mon, Feb 24, 2014 at 12:53 PM, Adam N=
evraumont <span dir=3D"ltr">&lt;<a href=3D"mailto:afn@theorem.ca" target=3D=
"_blank">afn@theorem.ca</a>&gt;</span> wrote:<br><blockquote class=3D"gmail=
_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:=
1ex">

<div dir=3D"ltr"><br><br>On Saturday, February 22, 2014 12:21:28 AM UTC-5, =
<a href=3D"mailto:myri...@gmail.com" target=3D"_blank">myri...@gmail.com</a=
> wrote:<blockquote class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8=
ex;border-left:1px #ccc solid;padding-left:1ex">

<div dir=3D"ltr">It&#39;d be hacky as all hell, but there is a way that ove=
rloading ?: could work without losing short-circuiting or breaking the lang=
uage <i>too</i> much.=C2=A0 I don&#39;t really know why you&#39;d want to o=
verload ?: in the first place, but this could work:<br>

<br>const ParentOfLeftAndRight &amp;operator ?:(<br>=C2=A0=C2=A0=C2=A0 cons=
t Conditional &amp;conditional,<br>=C2=A0=C2=A0=C2=A0 std::function&lt;cons=
t Left &amp;()&gt; getLeft,<br>=C2=A0=C2=A0=C2=A0 std::function&lt;const Ri=
ght &amp;&gt;() getRight)<br>{<br>=C2=A0 return conditional.Evaluate() ? ge=
tLeft() : getRight();<br>

}<br><br>In other words, have the compiler generate lambdas for the express=
ions on the left and right sides of the colon, and try to find an operator =
?: function that has an overload that will take that argument trio.<br>

</div></blockquote><div>=C2=A0Rather,<br>template&lt;typename LeftExpr, typ=
ename RightExpr&gt;<br>std::common_type_t&lt; std::result_of_t&lt;LeftExpr(=
)&gt;, std::result_of_t&lt;RightExpr()&gt; &gt; operator?:(<br>=C2=A0=C2=A0=
 Conditional const&amp; condition,<br>

=C2=A0=C2=A0 LeftExpr&amp;&amp; lhs,<br>=C2=A0=C2=A0 RightExpr &amp;&amp; r=
hs<br>)<br>{<br>=C2=A0 if (condition)<br>=C2=A0=C2=A0=C2=A0 return std::for=
ward&lt;LeftExpr&gt;(lhs)();<br>=C2=A0 else<br>=C2=A0=C2=A0=C2=A0 return st=
d::forward&lt;RightExpr&gt;(rhs)();<br>}<br>where<br>cond?lhs:rhs;<br>

is transformed into<br>operator?:( cond, [&amp;]{return lhs;}, [&amp;]{retu=
rn rhs;} )<br>with maybe some verbage to make sure perfect forwarding occur=
s.<br><br>You could naturally do the same with &amp;&amp; and ||.=C2=A0 Som=
e way (maybe something as hacky as the int argument to ++) to distinguish b=
etween the short-circuit and &quot;traditional&quot; overloads of &amp;&amp=
; and ||.<br>

<br>Short-circuit overloads could be preferred, or it could be ambiguous if=
 both exist and are otherwise equally good.<br><br>Adding a non-short-circu=
it ?: seems like a bad idea, for the same reason why nobody wants to overri=
de &amp;&amp; and ||.=C2=A0 But if we first added short-circuit &amp;&amp; =
and ||, we can add short-circuit ?: and skip the non-short-circuit version.=
...<span class=3D"HOEnZb"><font color=3D"#888888"><br>

<br><br>=C2=A0=C2=A0 <br></font></span></div></div><span class=3D"HOEnZb"><=
font color=3D"#888888">

<p></p>

-- <br>
=C2=A0<br>
--- <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%2Bunsubscribe@isocpp.org" target=3D=
"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank">std-proposals@isocpp.org</a>.<br>
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/" target=3D"_blank">http://groups.google.com/a/isocpp.org/gro=
up/std-proposals/</a>.<br>
</font></span></blockquote></div><br></div>

<p></p>

-- <br />
&nbsp;<br />
--- <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 std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

--f46d0444711d5755f004f32de666--

.
