Topic: Proxy objects and casting to rvalues
Author: =?UTF-8?Q?Aar=C3=B3n_Bueno_Villares?= <abv150ci@gmail.com>
Date: Sat, 8 Apr 2017 23:21:02 -0700 (PDT)
Raw View
------=_Part_4_186886583.1491718862126
Content-Type: multipart/alternative;
boundary="----=_Part_5_1288154988.1491718862127"
------=_Part_5_1288154988.1491718862127
Content-Type: text/plain; charset=UTF-8
Hello! And sorry for my english.
Let's consider that example, taking from one comments of the Eric Niebler's
blog:
std::vector<bool> v{true,false,true};
for (auto i : v)
i = false; // (1)
The range-based for is modifying the vector, since it's taking copies of
the proxy object. However, the proxy object is a reference-wrapper. And
what is the property of a reference? That if I need to get a copy, a need a
copy of the value type, not the reference type. I have reading some
attempts to propose auto deduction rules and the sort, but the seems not
satisfaying But, why not adding to the language the posibility of
specifying a dual type according if they is being used as reference or
value type?
For example:
struct Iterator
{
// other code
value_type T;
reference R;
reference ! value_type operator*() const { return reference(/**/); }
};
Iterator it = container.begin();
auto& ref = *it; // Compilation error, obvious. `reference` is a rvalue.
auto const& ref = *it; // Ok, deduced as reference const&
*it = something; // Ok, the proxy still takes control.
auto value = *it; // Deduced as value_type! I have a copy of the real
value!!
reference value = *it; // Compilation error?
The reference type, of course, must be convertible to the "after !" type. I
have given the example with the iterator case, but it can be applied to any
non-void function. The choice of `!` is because no specific reason. I just
thought that it can be easier for parsers, since can't be confused with any
other declarator.
For the `vector<bool>` case:
template<...>
class vector<bool, ...>
{
using value_type = bool;
using reference = bit_wrapper;
reference ! value_type operator*() const { return
bit_wrapper(/**/); }
};
Or even better:
template<...>
class vector<bool, ...>
{
using value_type = bool;
using reference = bit_wrapper ! value_type;
reference operator*() const { return bit_wrapper(/**/) }
};
That way, the semantics of the `reference` and `value_type` are keep
separated. It just specifies what happens when copying. The `auto`
deduction rules aren't modified, since, when copying, a cast is performing.
What is seen by auto is the type of the temporary object result of the
casting. What changes is the effects of the copy operation, that before
doing a copy, a casting is performed (I don't know what to say about moving
the combined type).
auto const& ref = *it;
auto val = ref;
`ref` is deduced as `bit_wrapper ! bool const&" (a.k.a bit_wrapper const&
untill is copied), and val is deduced as "bool". The idea is to specify
that a type must fallback to another type when using it as value, and the
type must be of course convertible to it. That shouldn't be specified in
the `type` definition (inside the class). The `type` is unconnected to what
types can be combined to (except that it must be convertible to, but a
conversion can be available without having that posible combination in mind
in the first place). You could even create variables or returning objects
of those combined types.
wrapper ! value_type val(...); // I'm creating a true reference wrapper
(wrapper, by itself, is not a true reference till combined with its value
type).
auto v = val; // v is value_type.
But it's harder to say what will be the different rules about the combined
types in the different expressions it could appear, and I know that is a
very big change for a very specific case (proxy "things"), but I think, if
the rules are well design and very enclosed to only what it's needed, maybe
it can be, maybe and at least, arguable, without touching current STL's
algorithm implementations.
--
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/9da2eb61-ab97-4b03-933e-da18139d77c0%40isocpp.org.
------=_Part_5_1288154988.1491718862127
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hello! And sorry for my english.<div><br></div><div>Let=
9;s consider that example, taking from one comments of the Eric Niebler'=
;s blog:<div><br></div><div><div>=C2=A0 =C2=A0 std::vector<bool> v{tr=
ue,false,true};</div><div>=C2=A0 =C2=A0=C2=A0</div><div>=C2=A0 =C2=A0 for (=
auto i : v)</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 i =3D false; =C2=A0// (1)=
</div></div><div><br></div><div>The range-based for is modifying the vector=
, since it's taking copies of the proxy object. However, the proxy obje=
ct is a reference-wrapper. And what is the property of a reference? That if=
I need to get a copy, a need a copy of the value type, not the reference t=
ype. I have reading some attempts to propose auto deduction rules and the s=
ort, but the seems not satisfaying But, why not adding to the language the =
posibility of specifying a dual type according if they is being used as ref=
erence or value type?</div><div><br></div><div>For example:</div><div><br><=
/div><div>=C2=A0 =C2=A0 struct Iterator</div><div>=C2=A0 =C2=A0 {</div><div=
>=C2=A0 =C2=A0 =C2=A0 =C2=A0 // other code</div><div>=C2=A0 =C2=A0 =C2=A0 =
=C2=A0 value_type T;</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 reference R;</di=
v><div><br></div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 reference ! value_type op=
erator*() const { return reference(/**/); }</div><div>=C2=A0 =C2=A0 };</div=
><div><br></div><div>=C2=A0 =C2=A0 Iterator it =3D container.begin();</div>=
<div><br></div><div>=C2=A0 =C2=A0 auto& ref =3D *it; // Compilation err=
or, obvious. `reference` is a rvalue.</div><div>=C2=A0 =C2=A0 auto const&am=
p; ref =3D *it; // Ok, deduced as reference const&</div><div><br></div>=
<div>=C2=A0 =C2=A0 *it =3D something; // Ok, the proxy still takes control.=
</div><div><br></div><div>=C2=A0 =C2=A0 auto value =3D *it; // Deduced as v=
alue_type! I have a copy of the real value!!</div><div>=C2=A0 =C2=A0 refere=
nce value =3D *it; // Compilation error?</div><div><br></div><div>The refer=
ence type, of course, must be convertible to the "after !" type. =
I have given the example with the iterator case, but it can be applied to a=
ny non-void function. The choice of `!` is because no specific reason. I ju=
st thought that it can be easier for parsers, since can't be confused w=
ith any other declarator.</div><div><br></div><div>For the `vector<bool&=
gt;` case:</div><div><br></div><div>=C2=A0 =C2=A0 template<...></div>=
<div>=C2=A0 =C2=A0 class vector<bool, ...></div><div>=C2=A0 =C2=A0 {<=
/div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0using value_type =3D boo=
l;</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0using reference =3D b=
it_wrapper;</div><div><br></div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0reference ! value_type operator*() const { return bit_wrapper(/**/); }</=
div><div>=C2=A0 =C2=A0 };</div><div><br></div><div>Or even better:</div><di=
v><br></div><div><div>=C2=A0 =C2=A0 template<...></div><div>=C2=A0 =
=C2=A0 class vector<bool, ...></div><div>=C2=A0 =C2=A0 {</div><div>=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0using value_type =3D bool;</div><d=
iv>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0using reference =3D bit_wrapper=
! value_type;</div><div><br></div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0reference operator*() const { return bit_wrapper(/**/) }</div><div>=
=C2=A0 =C2=A0 };</div></div><div><br></div><div>That way, the semantics of =
the `reference` and `value_type` are keep separated. It just specifies what=
happens when copying. The `auto` deduction rules aren't modified, sinc=
e, when copying, a cast is performing. What is seen by auto is the type of =
the temporary object result of the casting. What changes is the effects of =
the copy operation, that before doing a copy, a casting is performed (I don=
't know what to say about moving the combined type).</div><div><br></di=
v><div>=C2=A0 =C2=A0 auto const& ref =3D *it;</div><div>=C2=A0 =C2=A0 a=
uto val =3D ref;</div><div><br></div><div>`ref` is deduced as `bit_wrapper =
! bool const&" (a.k.a bit_wrapper const& untill is copied), an=
d val is deduced as "bool". The idea is to specify that a type mu=
st fallback to another type when using it as value, and the type must be of=
course convertible to it. That shouldn't be specified in the `type` de=
finition (inside the class). The `type` is unconnected to what types can be=
combined to (except that it must be convertible to, but a conversion can b=
e available without having that posible combination in mind in the first pl=
ace). You could even create variables or returning objects of those combine=
d types.</div><div><br></div><div>=C2=A0 =C2=A0 wrapper ! value_type val(..=
..); // I'm creating a true reference wrapper (wrapper, by itself, is no=
t a true reference till combined with its value type).</div><div>=C2=A0 =C2=
=A0 auto v =3D val; // v is value_type.</div><div><br></div><div>But it'=
;s harder to say what will be the different rules about the combined types =
in the different expressions it could appear, and I know that is a very big=
change for a very specific case (proxy "things"), but I think, i=
f the rules are well design and very enclosed to only what it's needed,=
maybe it can be, maybe and at least, arguable, without touching current ST=
L's algorithm implementations.<br></div></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/9da2eb61-ab97-4b03-933e-da18139d77c0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/9da2eb61-ab97-4b03-933e-da18139d77c0=
%40isocpp.org</a>.<br />
------=_Part_5_1288154988.1491718862127--
------=_Part_4_186886583.1491718862126--
.
Author: =?UTF-8?Q?Aar=C3=B3n_Bueno_Villares?= <abv150ci@gmail.com>
Date: Sun, 9 Apr 2017 08:43:37 +0200
Raw View
--94eb2c0954540d8d13054cb6300a
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
My first paragraph is closed of not being understandable, sorry:
The range-based-for is modifying the vector, since it's taking copies of
the proxy objects. However, each proxy object is a reference-wrapper. And
what is the property of a reference? That if I need to get a copy, I need a
copy of the value type, not the reference itselft. I was reading some
attempts to propose "auto operators" and the sort, but they seemed not
satisfying. But, why not adding to the language the posibility of
specifying dual types according to if the type is being used as reference
or value type?
On 9 April 2017 at 08:21, Aar=C3=B3n Bueno Villares <abv150ci@gmail.com> wr=
ote:
> Hello! And sorry for my english.
>
> Let's consider that example, taking from one comments of the Eric
> Niebler's blog:
>
> std::vector<bool> v{true,false,true};
>
> for (auto i : v)
> i =3D false; // (1)
>
> The range-based for is modifying the vector, since it's taking copies of
> the proxy object. However, the proxy object is a reference-wrapper. And
> what is the property of a reference? That if I need to get a copy, a need=
a
> copy of the value type, not the reference type. I have reading some
> attempts to propose auto deduction rules and the sort, but the seems not
> satisfaying But, why not adding to the language the posibility of
> specifying a dual type according if they is being used as reference or
> value type?
>
> For example:
>
> struct Iterator
> {
> // other code
> value_type T;
> reference R;
>
> reference ! value_type operator*() const { return reference(/**/)=
;
> }
> };
>
> Iterator it =3D container.begin();
>
> auto& ref =3D *it; // Compilation error, obvious. `reference` is a
> rvalue.
> auto const& ref =3D *it; // Ok, deduced as reference const&
>
> *it =3D something; // Ok, the proxy still takes control.
>
> auto value =3D *it; // Deduced as value_type! I have a copy of the re=
al
> value!!
> reference value =3D *it; // Compilation error?
>
> The reference type, of course, must be convertible to the "after !" type.
> I have given the example with the iterator case, but it can be applied to
> any non-void function. The choice of `!` is because no specific reason. I
> just thought that it can be easier for parsers, since can't be confused
> with any other declarator.
>
> For the `vector<bool>` case:
>
> template<...>
> class vector<bool, ...>
> {
> using value_type =3D bool;
> using reference =3D bit_wrapper;
>
> reference ! value_type operator*() const { return
> bit_wrapper(/**/); }
> };
>
> Or even better:
>
> template<...>
> class vector<bool, ...>
> {
> using value_type =3D bool;
> using reference =3D bit_wrapper ! value_type;
>
> reference operator*() const { return bit_wrapper(/**/) }
> };
>
> That way, the semantics of the `reference` and `value_type` are keep
> separated. It just specifies what happens when copying. The `auto`
> deduction rules aren't modified, since, when copying, a cast is performin=
g.
> What is seen by auto is the type of the temporary object result of the
> casting. What changes is the effects of the copy operation, that before
> doing a copy, a casting is performed (I don't know what to say about movi=
ng
> the combined type).
>
> auto const& ref =3D *it;
> auto val =3D ref;
>
> `ref` is deduced as `bit_wrapper ! bool const&" (a.k.a bit_wrapper const&
> untill is copied), and val is deduced as "bool". The idea is to specify
> that a type must fallback to another type when using it as value, and the
> type must be of course convertible to it. That shouldn't be specified in
> the `type` definition (inside the class). The `type` is unconnected to wh=
at
> types can be combined to (except that it must be convertible to, but a
> conversion can be available without having that posible combination in mi=
nd
> in the first place). You could even create variables or returning objects
> of those combined types.
>
> wrapper ! value_type val(...); // I'm creating a true reference
> wrapper (wrapper, by itself, is not a true reference till combined with i=
ts
> value type).
> auto v =3D val; // v is value_type.
>
> But it's harder to say what will be the different rules about the combine=
d
> types in the different expressions it could appear, and I know that is a
> very big change for a very specific case (proxy "things"), but I think, i=
f
> the rules are well design and very enclosed to only what it's needed, may=
be
> it can be, maybe and at least, arguable, without touching current STL's
> algorithm implementations.
>
> --
> 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/9da2eb61-ab97-4b03-
> 933e-da18139d77c0%40isocpp.org
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/9da2eb61-ab=
97-4b03-933e-da18139d77c0%40isocpp.org?utm_medium=3Demail&utm_source=3Dfoot=
er>
> .
>
--=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/CAMbYJhYK55BWCgLxcYHRzwo4MOgyFe68mnVcPvaTrAXyWUn=
wOA%40mail.gmail.com.
--94eb2c0954540d8d13054cb6300a
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">My first paragraph is closed of not being understandable, =
sorry:<br><br>The range-based-for is modifying the vector, since it's t=
aking copies of the proxy objects. However, each proxy object is a referenc=
e-wrapper. And what is the property of a reference? That if I need to get a=
copy, I need a copy of the value type, not the reference itselft. I was re=
ading some attempts to propose "auto operators" and the sort, but=
they seemed not satisfying. But, why not adding to the language the posibi=
lity of specifying dual types according to if the type is being used as ref=
erence or value type?<br><br>=C2=A0</div><div class=3D"gmail_extra"><br><di=
v class=3D"gmail_quote">On 9 April 2017 at 08:21, Aar=C3=B3n Bueno Villares=
<span dir=3D"ltr"><<a href=3D"mailto:abv150ci@gmail.com" target=3D"_bla=
nk">abv150ci@gmail.com</a>></span> wrote:<br><blockquote class=3D"gmail_=
quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1=
ex"><div dir=3D"ltr">Hello! And sorry for my english.<div><br></div><div>Le=
t's consider that example, taking from one comments of the Eric Niebler=
's blog:<div><br></div><div><div>=C2=A0 =C2=A0 std::vector<bool> =
v{true,false,true};</div><div>=C2=A0 =C2=A0=C2=A0</div><div>=C2=A0 =C2=A0 f=
or (auto i : v)</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 i =3D false; =C2=A0//=
(1)</div></div><div><br></div><div>The range-based for is modifying the ve=
ctor, since it's taking copies of the proxy object. However, the proxy =
object is a reference-wrapper. And what is the property of a reference? Tha=
t if I need to get a copy, a need a copy of the value type, not the referen=
ce type. I have reading some attempts to propose auto deduction rules and t=
he sort, but the seems not satisfaying But, why not adding to the language =
the posibility of specifying a dual type according if they is being used as=
reference or value type?</div><div><br></div><div>For example:</div><div><=
br></div><div>=C2=A0 =C2=A0 struct Iterator</div><div>=C2=A0 =C2=A0 {</div>=
<div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 // other code</div><div>=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 value_type T;</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 reference R;=
</div><div><br></div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 reference ! value_typ=
e operator*() const { return reference(/**/); }</div><div>=C2=A0 =C2=A0 };<=
/div><div><br></div><div>=C2=A0 =C2=A0 Iterator it =3D container.begin();</=
div><div><br></div><div>=C2=A0 =C2=A0 auto& ref =3D *it; // Compilation=
error, obvious. `reference` is a rvalue.</div><div>=C2=A0 =C2=A0 auto cons=
t& ref =3D *it; // Ok, deduced as reference const&</div><div><br></=
div><div>=C2=A0 =C2=A0 *it =3D something; // Ok, the proxy still takes cont=
rol.</div><div><br></div><div>=C2=A0 =C2=A0 auto value =3D *it; // Deduced =
as value_type! I have a copy of the real value!!</div><div>=C2=A0 =C2=A0 re=
ference value =3D *it; // Compilation error?</div><div><br></div><div>The r=
eference type, of course, must be convertible to the "after !" ty=
pe. I have given the example with the iterator case, but it can be applied =
to any non-void function. The choice of `!` is because no specific reason. =
I just thought that it can be easier for parsers, since can't be confus=
ed with any other declarator.</div><div><br></div><div>For the `vector<b=
ool>` case:</div><div><br></div><div>=C2=A0 =C2=A0 template<...></=
div><div>=C2=A0 =C2=A0 class vector<bool, ...></div><div>=C2=A0 =C2=
=A0 {</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0using value_type =
=3D bool;</div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0using referenc=
e =3D bit_wrapper;</div><div><br></div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=
=A0 =C2=A0reference ! value_type operator*() const { return bit_wrapper(/**=
/); }</div><div>=C2=A0 =C2=A0 };</div><div><br></div><div>Or even better:</=
div><div><br></div><div><div>=C2=A0 =C2=A0 template<...></div><div>=
=C2=A0 =C2=A0 class vector<bool, ...></div><div>=C2=A0 =C2=A0 {</div>=
<div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0using value_type =3D bool;</d=
iv><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0using reference =3D bit_wr=
apper ! value_type;</div><div><br></div><div>=C2=A0 =C2=A0 =C2=A0 =C2=A0 =
=C2=A0 =C2=A0reference operator*() const { return bit_wrapper(/**/) }</div>=
<div>=C2=A0 =C2=A0 };</div></div><div><br></div><div>That way, the semantic=
s of the `reference` and `value_type` are keep separated. It just specifies=
what happens when copying. The `auto` deduction rules aren't modified,=
since, when copying, a cast is performing. What is seen by auto is the typ=
e of the temporary object result of the casting. What changes is the effect=
s of the copy operation, that before doing a copy, a casting is performed (=
I don't know what to say about moving the combined type).</div><div><br=
></div><div>=C2=A0 =C2=A0 auto const& ref =3D *it;</div><div>=C2=A0 =C2=
=A0 auto val =3D ref;</div><div><br></div><div>`ref` is deduced as `bit_wra=
pper ! bool const&" (a.k.a bit_wrapper const& untill is copied=
), and val is deduced as "bool". The idea is to specify that a ty=
pe must fallback to another type when using it as value, and the type must =
be of course convertible to it. That shouldn't be specified in the `typ=
e` definition (inside the class). The `type` is unconnected to what types c=
an be combined to (except that it must be convertible to, but a conversion =
can be available without having that posible combination in mind in the fir=
st place). You could even create variables or returning objects of those co=
mbined types.</div><div><br></div><div>=C2=A0 =C2=A0 wrapper ! value_type v=
al(...); // I'm creating a true reference wrapper (wrapper, by itself, =
is not a true reference till combined with its value type).</div><div>=C2=
=A0 =C2=A0 auto v =3D val; // v is value_type.</div><div><br></div><div>But=
it's harder to say what will be the different rules about the combined=
types in the different expressions it could appear, and I know that is a v=
ery big change for a very specific case (proxy "things"), but I t=
hink, if the rules are well design and very enclosed to only what it's =
needed, maybe it can be, maybe and at least, arguable, without touching cur=
rent STL's algorithm implementations.<span class=3D"HOEnZb"><font color=
=3D"#888888"><br></font></span></div></div></div><span class=3D"HOEnZb"><fo=
nt color=3D"#888888">
<p></p>
-- <br>
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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" target=3D"_=
blank">std-proposals+unsubscribe@<wbr>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>
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/9da2eb61-ab97-4b03-933e-da18139d77c0%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank">=
https://groups.google.com/a/<wbr>isocpp.org/d/msgid/std-<wbr>proposals/9da2=
eb61-ab97-4b03-<wbr>933e-da18139d77c0%40isocpp.org</a><wbr>.<br>
</font></span></blockquote></div><br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/CAMbYJhYK55BWCgLxcYHRzwo4MOgyFe68mnVc=
PvaTrAXyWUnwOA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAMbYJhYK55BWCgLx=
cYHRzwo4MOgyFe68mnVcPvaTrAXyWUnwOA%40mail.gmail.com</a>.<br />
--94eb2c0954540d8d13054cb6300a--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 9 Apr 2017 07:30:28 -0700 (PDT)
Raw View
------=_Part_5456_1052885705.1491748228687
Content-Type: multipart/alternative;
boundary="----=_Part_5457_97465389.1491748228688"
------=_Part_5457_97465389.1491748228688
Content-Type: text/plain; charset=UTF-8
What you're essentially asking is a modified form of something that has
been discussed since `auto` came into existence: the ability to specify the
type that will be deduced by `auto`. And proxy objects are the primary
justification for it, whether it is proxy iterators or lazy evaluation of
expressions (you want `auto` to evaluate the lazy expression, not store the
lazy intermediate).
The best syntactic form I've seen this in is via a member function of the
form:
class bit_wrapper
{
public:
Typename operator auto() const { <conversion expression> }
};
Note that this allows you to do arbitrary work in the conversion section.
Though we might add an `= default` version which is equivalent to implicit
conversion via `return *this;`.
This function is put in the actual type that would otherwise be deduced. I
think this works much better than your notion of adding it to the
`operator*` of the iterator (I assume; you put it in `vector<bool>`
instead, which has no `operator*`). Your way requires the compiler to
change what it is doing based on the return of a specific function call, so
it requires more work to do lazy expression evaluation, since you have to
apply it to every single function that returns a lazy result. Whereas here,
you just apply this to the lazy result *types*, and every use of those
types will automatically have this power.
The big, unanswered question with such a feature is mainly about what
exactly it affects. Does it only affect uses of the `auto` keyword for
variables? If it only affects `auto` variables, would that not be strange
with regard to generic lambda/Concepts TS `auto` parameters, which use
template argument deduction? Does it affect `decltype(auto)`, and if so,
how exactly? If it affects every form of deduction (template argument,
`decltype(auto)` and `auto`), then exactly how does it work?
--
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/a4e15473-7370-4a69-b126-58c48a64c401%40isocpp.org.
------=_Part_5457_97465389.1491748228688
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">What you're essentially asking is a modified form of s=
omething that has been discussed since `auto` came into existence: the abil=
ity to specify the type that will be deduced by `auto`. And proxy objects a=
re the primary justification for it, whether it is proxy iterators or lazy =
evaluation of expressions (you want `auto` to evaluate the lazy expression,=
not store the lazy intermediate).<br><br>The best syntactic form I've =
seen this in is via a member function of the form:<br><br><div style=3D"bac=
kground-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border=
-style: solid; border-width: 1px; overflow-wrap: break-word;" class=3D"pret=
typrint"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span st=
yle=3D"color: #008;" class=3D"styled-by-prettify">class</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> bit_wrapper<br></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=
: #008;" class=3D"styled-by-prettify">public</span><span style=3D"color: #6=
60;" class=3D"styled-by-prettify">:</span><span style=3D"color: #000;" clas=
s=3D"styled-by-prettify"><br>=C2=A0 =C2=A0 </span><span style=3D"color: #60=
6;" class=3D"styled-by-prettify">Typename</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=
=3D"styled-by-prettify">operator</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">auto</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">()</span><span style=3D"color: #000;" class=3D"styled-by-prettify"=
> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">const</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"> </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><span style=3D"color: #000;" =
class=3D"styled-by-prettify">conversion expression</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">></span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> </span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">}</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"><br></span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">};</span></div></code></div><br>Note that this allows you to do a=
rbitrary work in the conversion section. Though we might add an `=3D defaul=
t` version which is equivalent to implicit conversion via `return *this;`.<=
br><br>This function is put in the actual type that would otherwise be dedu=
ced. I think this works much better than your notion of adding it to the `o=
perator*` of the iterator (I assume; you put it in `vector<bool>` ins=
tead, which has no `operator*`). Your way requires the compiler to change w=
hat it is doing based on the return of a specific function call, so it requ=
ires more work to do lazy expression evaluation, since you have to apply it=
to every single function that returns a lazy result. Whereas here, you jus=
t apply this to the lazy result <i>types</i>, and every use of those types =
will automatically have this power.<br><br>The big, unanswered question wit=
h such a feature is mainly about what exactly it affects. Does it only affe=
ct uses of the `auto` keyword for variables? If it only affects `auto` vari=
ables, would that not be strange with regard to generic lambda/Concepts TS =
`auto` parameters, which use template argument deduction? Does it affect `d=
ecltype(auto)`, and if so, how exactly? If it affects every form of deducti=
on (template argument, `decltype(auto)` and `auto`), then exactly how does =
it work?<br></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" 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/a4e15473-7370-4a69-b126-58c48a64c401%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/a4e15473-7370-4a69-b126-58c48a64c401=
%40isocpp.org</a>.<br />
------=_Part_5457_97465389.1491748228688--
------=_Part_5456_1052885705.1491748228687--
.
Author: =?UTF-8?Q?Aar=C3=B3n_Bueno_Villares?= <abv150ci@gmail.com>
Date: Sun, 9 Apr 2017 08:51:46 -0700 (PDT)
Raw View
------=_Part_1024_2110165171.1491753106814
Content-Type: multipart/alternative;
boundary="----=_Part_1025_1524697587.1491753106814"
------=_Part_1025_1524697587.1491753106814
Content-Type: text/plain; charset=UTF-8
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
> been discussed since `auto` came into existence: the ability to specify the
> type that will be deduced by `auto`. And proxy objects are the primary
> justification for it, whether it is proxy iterators or lazy evaluation of
> expressions (you want `auto` to evaluate the lazy expression, not store the
> lazy intermediate).
>
> The best syntactic form I've seen this in is via a member function of the
> form:
>
> class bit_wrapper
> {
> public:
> Typename operator auto() const { <conversion expression> }
> };
>
> Note that this allows you to do arbitrary work in the conversion section.
> Though we might add an `= default` version which is equivalent to implicit
> conversion via `return *this;`.
>
>
But I think it makes impossible to use `auto` to copy instances of that
type. For instance:
```C++
struct wrapper { value_type operator auto() const { /**/ } };
auto wrapper_obj = wrapper_factory::give_me_a_new_wrapper();
```
or any copy I have to do with the wrapper (or any intermediary function
returning it), will be deduced as `value_type`. However, I'm still working
with a `wrapper`!! The "reference nature" has not been start yet. That
conversion operator forces me to think a bit more anytime I want to use
`auto`.
What if I want to bind the object to a reference, to modify the real object
that is behind?
```C++
auto const& w = *it;
w = something; // The wrapped object must be modified, as a real reference.
```
Since the proxy represents a reference, must be trated as such when taking
it by reference or by value when it is still a "object proxy". But when
passing it as "pure proxy" or "pure reference proxy" or the way you want to
call it, then it must be cast to the secondary type when copying. The `!
value_type` is not a new type, but some kind of conversion qualifier.
> This function is put in the actual type that would otherwise be deduced. I
> think this works much better than your notion of adding it to the
> `operator*` of the iterator (I assume; you put it in `vector<bool>`
> instead, which has no `operator*`). Your way requires the compiler to
> change what it is doing based on the return of a specific function call, so
> it requires more work to do lazy expression evaluation, since you have to
> apply it to every single function that returns a lazy result.
>
>
Yes, the whole thing it's crazy complex semantically. Too much context.
The big, unanswered question with such a feature is mainly about what
> exactly it affects. Does it only affect uses of the `auto` keyword for
> variables? If it only affects `auto` variables, would that not be strange
> with regard to generic lambda/Concepts TS `auto` parameters, which use
> template argument deduction? Does it affect `decltype(auto)`, and if so,
> how exactly? If it affects every form of deduction (template argument,
> `decltype(auto)` and `auto`), then exactly how does it work?
>
My approach has the same problems. The thing is that, when you are
constructing a new object from a combined type, you have too much
situations (whe asume that `value_type` cannot be a reference, but
`wrapper` does):
```C++
/* When expr is T ! V (T is not referfence) */
// (1)
T a = expr; // Error or do we want to copy the proxy object losing the
convert-when-copying nature?
T& ra = expr; // Same situation.
T const& ra = expr; // Same situation.
// (2)
T!V a = expr; // Ok, we copy `T`.
T!V& a = expr; // Ok, if expr returns an `lvalue`.
T!V const& a = expr; // Ok.
// (3)
auto a = expr; // Ok, we cast to V and then copy. auto decuded as V
auto& a2 = expr; // auto deduced as T!V& (a.k.a T&)
auto const& a3 = expr; // auto decuded as T!V const& (a.k.a T const&).
auto a4 = a2; // Ok, auto deduced as V since a2 is T!V&
```
The think is that, when dealing with iterators, you don't have two types,
but have three:
* value_type represents the storage. What `sort` needs when doing copies.
* sequence_type represents the view that the iterator gives to you.
* reference is something in the middle, with allows to comunicate between
both worlds. What `operator*` returns.
`sequence_type` doesn't need to be explicitely defined, not added to the
Iterator concept or something. It is what users expect when reading the
iterator (for example, the parameters of the functors passed to
`for_each`). With `reference` being convertible to user parameters is
enough. `value_type` is what algorithms and user expects for local storage,
to transform and save back the value to the iterator. The `reference` type
is then tricked to allow one of another usage depending on the context, in
a way more or less, transparent to current implementations.
--
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/3bf83fd7-8b87-45ca-ac8b-3b856776acac%40isocpp.org.
------=_Part_1025_1524697587.1491753106814
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div><br></div>On Sunday, 9 April 2017 16:30:28 UTC+2, Nic=
ol Bolas wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D"lt=
r">What you're essentially asking is a modified form of something that =
has been discussed since `auto` came into existence: the ability to specify=
the type that will be deduced by `auto`. And proxy objects are the primary=
justification for it, whether it is proxy iterators or lazy evaluation of =
expressions (you want `auto` to evaluate the lazy expression, not store the=
lazy intermediate).<br><br>The best syntactic form I've seen this in i=
s via a member function of the form:<br><br><div style=3D"background-color:=
rgb(250,250,250);border-color:rgb(187,187,187);border-style:solid;border-wi=
dth:1px"><code><div><span style=3D"color:#008">class</span><span style=3D"c=
olor:#000"> bit_wrapper<br></span><span style=3D"color:#660">{</span><span =
style=3D"color:#000"><br></span><span style=3D"color:#008">public</span><sp=
an style=3D"color:#660">:</span><span style=3D"color:#000"><br>=C2=A0 =C2=
=A0 </span><span style=3D"color:#606">Typename</span><span style=3D"color:#=
000"> </span><span 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><span style=3D"color:#000"> </span><span style=3D"color:#660">=
{</span><span style=3D"color:#000"> </span><span style=3D"color:#660"><<=
/span><span style=3D"color:#000">conversion expression</span><span style=3D=
"color:#660">></span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#660">}</span><span style=3D"color:#000"><br></span><span style=3D"col=
or:#660">};</span></div></code></div><br>Note that this allows you to do ar=
bitrary work in the conversion section. Though we might add an `=3D default=
` version which is equivalent to implicit conversion via `return *this;`.<b=
r><br></div></blockquote><div><br></div><div>But I think it makes impossibl=
e to use `auto` to copy instances of that type. For instance:<br><br>```C++=
<br>struct wrapper { value_type operator auto() const { /**/ } };<div>auto =
wrapper_obj =3D wrapper_factory::give_me_a_new_wrapper();=C2=A0<br>```</div=
><div><br>or any copy I have to do with the wrapper (or any intermediary fu=
nction returning it), will be deduced as `value_type`. However, I'm sti=
ll working with a `wrapper`!! The "reference nature" has not been=
start yet. That conversion operator forces me to think a bit more anytime =
I want to use `auto`.=C2=A0<br><br>What if I want to bind the object to a r=
eference, to modify the real object that is behind?<br><br>```C++<br>auto c=
onst& w =3D *it;<br>w =3D something; // The wrapped object must be modi=
fied, as a real reference.<br>```</div><div><br>Since the proxy represents =
a reference, must be trated as such when taking it by reference or by value=
when it is still a "object proxy". But when passing it as "=
pure proxy" or "pure reference proxy" or the way you want to=
call it, then it must be cast to the secondary type when copying. The `! v=
alue_type` is not a new type, but some kind of conversion qualifier.</div><=
/div><div>=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 dir=
=3D"ltr">This function is put in the actual type that would otherwise be de=
duced. I think this works much better than your notion of adding it to the =
`operator*` of the iterator (I assume; you put it in `vector<bool>` i=
nstead, which has no `operator*`). Your way requires the compiler to change=
what it is doing based on the return of a specific function call, so it re=
quires more work to do lazy expression evaluation, since you have to apply =
it to every single function that returns a lazy result.<br><br></div></bloc=
kquote><div><br></div><div>Yes, the whole thing it's crazy complex sema=
ntically. Too much context.</div><div><br></div><blockquote class=3D"gmail_=
quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;pa=
dding-left: 1ex;"><div dir=3D"ltr">The big, unanswered question with such a=
feature is mainly about what exactly it affects. Does it only affect uses =
of the `auto` keyword for variables? If it only affects `auto` variables, w=
ould that not be strange with regard to generic lambda/Concepts TS `auto` p=
arameters, which use template argument deduction? Does it affect `decltype(=
auto)`, and if so, how exactly? If it affects every form of deduction (temp=
late argument, `decltype(auto)` and `auto`), then exactly how does it work?=
<br></div></blockquote><div><br></div><div>My approach has the same problem=
s. The thing is that, when you are constructing a new object from a combine=
d type, you have too much situations (whe asume that `value_type` cannot be=
a reference, but `wrapper` does):<br></div><div><br>```C++<br>/* When expr=
is T ! V (T is not referfence) */</div><div>// (1)<br>T a =3D expr; // Err=
or or do we want to copy the proxy object losing the convert-when-copying n=
ature?</div><div>T& ra =3D expr; // Same situation.</div><div>T const&a=
mp; ra =3D expr; // Same situation.</div><div><br></div><div>// (2)</div><d=
iv>T!V a =3D expr; // Ok, we copy `T`.</div><div>T!V& a =3D expr; // Ok=
, if expr returns an `lvalue`.</div><div>T!V const& a =3D expr; // Ok.<=
/div><div><br></div><div>// (3)</div><div>auto a =3D expr; // Ok, we cast t=
o V and then copy. auto decuded as V</div><div>auto& a2 =3D expr; // au=
to deduced as T!V& (a.k.a T&)</div><div>auto const& a3 =3D expr=
; // auto decuded as T!V const& (a.k.a T const&).</div><div>auto a4=
=3D a2; // Ok, auto deduced as V since a2 is T!V&</div><div>```</div><=
div><br></div><div>The think is that, when dealing with iterators, you don&=
#39;t have two types, but have three:</div><div><br></div><div>* value_type=
represents the storage. What `sort` needs when doing copies.</div><div>* s=
equence_type represents the view that the iterator gives to you.</div><div>=
* reference is something in the middle, with allows to comunicate between b=
oth worlds. What `operator*` returns.</div><div><br></div><div>`sequence_ty=
pe` doesn't need to be explicitely defined, not added to the Iterator c=
oncept or something. It is what users expect when reading the iterator (for=
example, the parameters of the functors passed to `for_each`). With `refer=
ence` being convertible to user parameters is enough. `value_type` is what =
algorithms and user expects for local storage, to transform and save back t=
he value to the iterator. The `reference` type is then tricked to allow one=
of another usage depending on the context, in a way more or less, transpar=
ent to current implementations.=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" 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/3bf83fd7-8b87-45ca-ac8b-3b856776acac%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3bf83fd7-8b87-45ca-ac8b-3b856776acac=
%40isocpp.org</a>.<br />
------=_Part_1025_1524697587.1491753106814--
------=_Part_1024_2110165171.1491753106814--
.
Author: Nicol Bolas <jmckesson@gmail.com>
Date: Sun, 9 Apr 2017 11:00:35 -0700 (PDT)
Raw View
------=_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'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"><</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's names and data aren't really part of the interface. People woul=
d instead use the base object's type and let implicit conversion handle=
things.<br><br>With `auto`, you now get the proxy object's type. But t=
hat'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'm still working with a `w=
rapper`!! The "reference nature" 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">"literal"</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">"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'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're mediators between =
some internal representation and the actual value you want to talk to. They=
're an implementation detail.<br><br>The common case use for proxies is=
to convert them to their real type; that's what people do with them 90=
% of the time. As such, if you don't want that, then you'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" 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--
.