220 32058 <6e471f98-15bf-4a85-8cc1-c4e0ea73a3d0@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Nicol Bolas <jmckesson@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Proxy objects and casting to rvalues
Date: Sun, 9 Apr 2017 11:00:35 -0700 (PDT)
Lines: 270
Approved: news@gmane.org
Message-ID: <6e471f98-15bf-4a85-8cc1-c4e0ea73a3d0@isocpp.org>
References: <9da2eb61-ab97-4b03-933e-da18139d77c0@isocpp.org>
 <CAMbYJhYK55BWCgLxcYHRzwo4MOgyFe68mnVcPvaTrAXyWUnwOA@mail.gmail.com>
 <a4e15473-7370-4a69-b126-58c48a64c401@isocpp.org>
 <3bf83fd7-8b87-45ca-ac8b-3b856776acac@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_290_156605213.1491760835147"
X-Trace: blaine.gmane.org 1491762891 12915 195.159.176.226 (9 Apr 2017 18:34:51 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Sun, 9 Apr 2017 18:34:51 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBBQ7NVHDQKGQEUSMI7EI@isocpp.org Sun Apr 09 20:34:41 2017
Return-path: <std-proposals+bncBCEKFTV6ZUMBBQ7NVHDQKGQEUSMI7EI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-io0-f197.google.com ([209.85.223.197])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBBQ7NVHDQKGQEUSMI7EI@isocpp.org>)
	id 1cxHfd-0002j0-39
	for gclcip-std-proposals@m.gmane.org; Sun, 09 Apr 2017 20:34:41 +0200
Original-Received: by mail-io0-f197.google.com with SMTP id a185sf40268383ioe.13
        for <gclcip-std-proposals@m.gmane.org>; Sun, 09 Apr 2017 11:34:42 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=nQe/9fhFM+icqJ0Q1aNCBY2OaHK1ck+pmzN6nqsWsDg=;
        b=xm9xw2ll6PLgl84fVdFZOJBfPZ/eos7uI3KrRGHWgK5P2m5NaaCFELyZ/fjSc9b0eU
         LSJt3BhsgqoPOpW3A5oaiUYIVv39m+hjK9pJ+8kVVLEpUxUQF0hkcpJq9RWNCXMpncsM
         fkfcWOiqBTg5vEga97rVsaQqp/Cn8fMFaYJBTauzVa3xYYKKFfuiXT30Mpa4JPo9X48v
         jewbTMrUPCzyY+NqC8rJ5F2r+XATH4RrCPkJHp3oIDDlNOA7VCFybbU+ukPGJ+bZZ+iZ
         X9KTM5OmpXXHT5kOp22rmu2bFKIH9DyGjcmhqjDc+vVGjFBIJNc0AuxJVHkyzqnD+83k
         2D+A==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=nQe/9fhFM+icqJ0Q1aNCBY2OaHK1ck+pmzN6nqsWsDg=;
        b=ods1soD+nNKIVk7zSOJWBEbdnMg+rNizI8rdMyNUd3pEZ5VYABwKZGTOFcO6n/qF6i
         CX0iKENTTDkYB27yoY11CnA7xsZt1kT4TCW4+OwEsthzfZDPysvARrf1VJUOpyfLX2mC
         UZUKdanXg/Y7cuNZrtj+NdKwYnAzqW458Wze/pKH6z9EZVn/+IW6ZKuA4NZ4c07X1CBz
         sT/CnDMsHY7kVUK2zLtCpDSZm8J9EnDFTDi40w18MH/SZMIXGuQFrJoD7n7uuv6vrZ9W
         /3tCpZ9/1wdbLscAkVZGk2TsloOidhzGJxyiodOY/tKq3XNcjgaqI6NtrTg5SLMlCu1X
         AKwQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:x-original-sender:reply-to:precedence
         :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=nQe/9fhFM+icqJ0Q1aNCBY2OaHK1ck+pmzN6nqsWsDg=;
        b=nfl46nGti52mMv6nxMajRi4QYhcF2MyNaYoji0laxIOXx/UBbuqepyoXtAv/KrMOTJ
         imw+mxQJcNlbU7fyZzSYCPZ5hAmCNmqKlvRaQ/vNf4jkOQVHxlvQ5hKPxQio/rYNy3Zf
         l0Jj/jrkHampovcemw2bM1hm5qFHvVyhWCL62elmSjg5+EE+MUJXGAh4qfLGheWLPq2P
         UrmOyYMt7ZUhjsU/7wxbTOrDzPCnwLoDhzhb5iD3biQ4xGPgxy9o/21jJ+r9KjuPzsEL
         9ONCAGoJ33iQ37sil6reoW2psmL/WefA9r9LrZ71FG/6o6+yIE5ewlJohuEBNt91qBeZ
         C97A==
X-Gm-Message-State: AFeK/H1d/C1tpv+kE3Kkwk9MpCrJa0Co60jQLP/s1QjT0q3u4iotD9xF/gY19t3nPITexQ==
X-Received: by 10.107.182.195 with SMTP id g186mr17660760iof.62.1491760836504;
        Sun, 09 Apr 2017 11:00:36 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.8.33 with SMTP id 30ls3488461oty.46.gmail; Sun, 09 Apr
 2017 11:00:35 -0700 (PDT)
X-Received: by 10.157.4.11 with SMTP id 11mr1030797otc.16.1491760835644;
        Sun, 09 Apr 2017 11:00:35 -0700 (PDT)
In-Reply-To: <3bf83fd7-8b87-45ca-ac8b-3b856776acac@isocpp.org>
X-Original-Sender: jmckesson@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: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:32058
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/32058>

------=_Part_290_156605213.1491760835147
Content-Type: multipart/alternative; 
	boundary="----=_Part_291_1946016572.1491760835148"

------=_Part_291_1946016572.1491760835148
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Sunday, April 9, 2017 at 11:51:46 AM UTC-4, Aar=C3=B3n Bueno Villares wr=
ote:
>
>
> On Sunday, 9 April 2017 16:30:28 UTC+2, Nicol Bolas wrote:
>>
>> What you're essentially asking is a modified form of something that has=
=20
>> been discussed since `auto` came into existence: the ability to specify =
the=20
>> type that will be deduced by `auto`. And proxy objects are the primary=
=20
>> justification for it, whether it is proxy iterators or lazy evaluation o=
f=20
>> expressions (you want `auto` to evaluate the lazy expression, not store =
the=20
>> lazy intermediate).
>>
>> The best syntactic form I've seen this in is via a member function of th=
e=20
>> form:
>>
>> class bit_wrapper
>> {
>> public:
>>     Typename operator auto() const { <conversion expression> }
>> };
>>
>> Note that this allows you to do arbitrary work in the conversion section=
..=20
>> Though we might add an `=3D default` version which is equivalent to impl=
icit=20
>> conversion via `return *this;`.
>>
>>
> But I think it makes impossible to use `auto` to copy instances of that=
=20
> type. For instance:
>
> ```C++
> struct wrapper { value_type operator auto() const { /**/ } };
> auto wrapper_obj =3D wrapper_factory::give_me_a_new_wrapper();=20
> ```
>

Yes. That is in fact the whole point.

Pre-`auto`, you would have had to explicitly state the name of the proxy=20
object's type if you wanted to store it. That prevented people from=20
accidentally storing proxy objects, since proxy types are usually internal=
=20
objects who's names and data aren't really part of the interface. People=20
would instead use the base object's type and let implicit conversion handle=
=20
things.

With `auto`, you now get the proxy object's type. But that's not what you=
=20
want most of the time.

By giving a type an `operator auto` function, we revert back to the=20
pre-C++11 behavior: if you want to store the proxy object, you *must* name=
=20
it.

or any copy I have to do with the wrapper (or any intermediary function=20
> returning it), will be deduced as `value_type`. However, I'm still workin=
g=20
> with a `wrapper`!! The "reference nature" has not been start yet. That=20
> conversion operator forces me to think a bit more anytime I want to use=
=20
> `auto`.
>

Would it?

Consider a string class that uses lazy expression evaluation. You do this:

auto str =3D someString + otherString + moreString + StringType("literal");

What does the user expect `str` to be? Odds are very good that the user=20
wanted `str` to be a *string* value, not a lazy expression object.=20
Especially not a lazy expression object that references a temporary that=20
has now been destroyed.

Pre-C++11, the user would have typed:

StringType str =3D someString + otherString + moreString + StringType(
"literal");

But post-C++11, the user would rather use `auto`. Except that they cannot,=
=20
because this will give them something other than `StringType`.

Note that by having `auto` deduce the proxy type, we introduce a bug: the=
=20
temporary stored by the lazy expression object is destroyed. By using=20
`operator auto`, we prevent that bug from being accidentally encountered.=
=20
It can *only* be encountered by explicitly naming the proxy object type.=20
And that makes it clear to everyone that there's a bug present.
=20

> What if I want to bind the object to a reference, to modify the real=20
> object that is behind?
>

Then you have to name the type.

You have to remember: you rarely want to play with proxy objects directly.=
=20
They're mediators between some internal representation and the actual value=
=20
you want to talk to. They're an implementation detail.

The common case use for proxies is to convert them to their real type;=20
that's what people do with them 90% of the time. As such, if you don't want=
=20
that, then you're going to have to name the type explicitly.

--=20
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 e=
mail 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/6e471f98-15bf-4a85-8cc1-c4e0ea73a3d0%40isocpp.or=
g.

------=_Part_291_1946016572.1491760835148
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">On Sunday, April 9, 2017 at 11:51:46 AM UTC-4, Aar=C3=B3n =
Bueno Villares wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=
=3D"ltr"><div><br></div>On Sunday, 9 April 2017 16:30:28 UTC+2, Nicol Bolas=
  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">What you&#=
39;re essentially asking is a modified form of something that has been disc=
ussed since `auto` came into existence: the ability to specify the type tha=
t will be deduced by `auto`. And proxy objects are the primary justificatio=
n for it, whether it is proxy iterators or lazy evaluation of expressions (=
you want `auto` to evaluate the lazy expression, not store the lazy interme=
diate).<br><br>The best syntactic form I&#39;ve seen this in is via a membe=
r function of the form:<br><br><div style=3D"background-color:rgb(250,250,2=
50);border-color:rgb(187,187,187);border-style:solid;border-width:1px"><cod=
e><div><span style=3D"color:#008">class</span><span style=3D"color:#000"> b=
it_wrapper<br></span><span style=3D"color:#660">{</span><span style=3D"colo=
r:#000"><br></span><span style=3D"color:#008">public</span><span style=3D"c=
olor:#660">:</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><spa=
n style=3D"color:#606">Typename</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#008">operator</span><span style=3D"color:#000"> </span>=
<span style=3D"color:#008">auto</span><span style=3D"color:#660">()</span><=
span style=3D"color:#000"> </span><span style=3D"color:#008">const</span><s=
pan style=3D"color:#000"> </span><span style=3D"color:#660">{</span><span s=
tyle=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><span sty=
le=3D"color:#000">conversion expression</span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">}</s=
pan><span style=3D"color:#000"><br></span><span style=3D"color:#660">};</sp=
an></div></code></div><br>Note that this allows you to do arbitrary work in=
 the conversion section. Though we might add an `=3D default` version which=
 is equivalent to implicit conversion via `return *this;`.<br><br></div></b=
lockquote><div><br></div><div>But I think it makes impossible to use `auto`=
 to copy instances of that type. For instance:<br><br>```C++<br>struct wrap=
per { value_type operator auto() const { /**/ } };<div>auto wrapper_obj =3D=
 wrapper_factory::give_me_a_<wbr>new_wrapper();=C2=A0<br>```</div></div></d=
iv></blockquote><div><br>Yes. That is in fact the whole point.<br><br>Pre-`=
auto`, you would have had to explicitly state the name of the proxy object&=
#39;s type if you wanted to store it. That prevented people from accidental=
ly storing proxy objects, since proxy types are usually internal objects wh=
o&#39;s names and data aren&#39;t really part of the interface. People woul=
d instead use the base object&#39;s type and let implicit conversion handle=
 things.<br><br>With `auto`, you now get the proxy object&#39;s type. But t=
hat&#39;s not what you want most of the time.<br><br>By giving a type an `o=
perator auto` function, we revert back to the pre-C++11 behavior: if you wa=
nt to store the proxy object, you <i>must</i> name it.<br><br></div><blockq=
uote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-lef=
t: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"ltr"><div><div>or any cop=
y I have to do with the wrapper (or any intermediary function returning it)=
, will be deduced as `value_type`. However, I&#39;m still working with a `w=
rapper`!! The &quot;reference nature&quot; has not been start yet. That con=
version operator forces me to think a bit more anytime I want to use `auto`=
..<br></div></div></div></blockquote><div><br>Would it?<br><br>Consider a st=
ring class that uses lazy expression evaluation. You do this:<br><br><div s=
tyle=3D"background-color: rgb(250, 250, 250); border-color: rgb(187, 187, 1=
87); border-style: solid; border-width: 1px; overflow-wrap: break-word;" cl=
ass=3D"prettyprint"><code class=3D"prettyprint"><div class=3D"subprettyprin=
t"><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span><sp=
an style=3D"color: #000;" class=3D"styled-by-prettify"> str </span><span st=
yle=3D"color: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"=
color: #000;" class=3D"styled-by-prettify"> someString </span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">+</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> otherString </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">+</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify"> moreString </span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">+</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"> </span><span style=3D"color: #606;" class=3D"styl=
ed-by-prettify">StringType</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">(</span><span style=3D"color: #080;" class=3D"styled-by-pre=
ttify">&quot;literal&quot;</span><span style=3D"color: #660;" class=3D"styl=
ed-by-prettify">);</span></div></code></div><br>What does the user expect `=
str` to be? Odds are very good that the user wanted `str` to be a <i>string=
</i> value, not a lazy expression object. Especially not a lazy expression =
object that references a temporary that has now been destroyed.<br><br>Pre-=
C++11, the user would have typed:<br><br><div style=3D"background-color: rg=
b(250, 250, 250); border-color: rgb(187, 187, 187); border-style: solid; bo=
rder-width: 1px; overflow-wrap: break-word;" class=3D"prettyprint"><code cl=
ass=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D"color: #60=
6;" class=3D"styled-by-prettify">StringType</span><span style=3D"color: #00=
0;" class=3D"styled-by-prettify"> str </span><span style=3D"color: #660;" c=
lass=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> someString </span><span style=3D"color: #660;" class=
=3D"styled-by-prettify">+</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> otherString </span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">+</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> moreString </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: #606;" class=3D"styled-by-prettify">StringT=
ype</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span=
><span style=3D"color: #080;" class=3D"styled-by-prettify">&quot;literal&qu=
ot;</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</spa=
n></div></code></div><br>But post-C++11, the user would rather use `auto`. =
Except that they cannot, because this will give them something other than `=
StringType`.<br><br>Note that by having `auto` deduce the proxy type, we in=
troduce a bug: the temporary stored by the lazy expression object is destro=
yed. By using `operator auto`, we prevent that bug from being accidentally =
encountered. It can <i>only</i> be encountered by explicitly naming the pro=
xy object type. And that makes it clear to everyone that there&#39;s a bug =
present.<br>=C2=A0</div><blockquote class=3D"gmail_quote" style=3D"margin: =
0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div d=
ir=3D"ltr"><div><div>What if I want to bind the object to a reference, to m=
odify the real object that is behind?<br></div></div></div></blockquote><di=
v><br>Then you have to name the type.<br><br>You have to remember: you rare=
ly want to play with proxy objects directly. They&#39;re mediators between =
some internal representation and the actual value you want to talk to. They=
&#39;re an implementation detail.<br><br>The common case use for proxies is=
 to convert them to their real type; that&#39;s what people do with them 90=
% of the time. As such, if you don&#39;t want that, then you&#39;re going t=
o have to name the type explicitly.</div><br></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/6e471f98-15bf-4a85-8cc1-c4e0ea73a3d0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/6e471f98-15bf-4a85-8cc1-c4e0ea73a3d0=
%40isocpp.org</a>.<br />

------=_Part_291_1946016572.1491760835148--

------=_Part_290_156605213.1491760835147--

.
