Topic: Generalized lambda captureturning values not


Author: Mikhail Semenov <mikhailsemenov1957@gmail.com>
Date: Fri, 27 Dec 2013 09:58:33 -0800 (PST)
Raw View
------=_Part_454_2810726.1388167113622
Content-Type: text/plain; charset=ISO-8859-1

I have looked at the following code (A is the type of x and y):

                    auto f1 = [x = std::move(x),&y]() mutable ->A
         {
            // some processing
            std::size_t n = x.size();
            for (std::size_t i = 0; i < n; i++)
                x[i] += y[i];
            // end some processing

            *return std::move(x);*  // should not the value be moved by
default here?
         };

I have noticed that if I don't write move in the return statement, the
value is copied.
Should not it be moved by default?

I think that if we capture a variable not by reference and  its value is
returned from lambda then move should be
performed by default. In the above example, it should be enough to write:

* return x;*



--

---
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/.

------=_Part_454_2810726.1388167113622
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div>I have looked at the following code (A is the type of=
 x and y):</div><div>&nbsp;</div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p; <font face=3D"courier new,monospace">auto f1 =3D [x =3D std::move(x),&am=
p;y]() mutable -&gt;A<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {=
<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // s=
ome processing<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; std::size_t n =3D x.size();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (std::size_t i =3D 0; i &lt; n; i++)<b=
r>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&=
nbsp;&nbsp;&nbsp; x[i] +=3D y[i];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;&nbsp;&nbsp;&nbsp; // end some processing</font></div><div><font =
face=3D"courier new,monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&n=
bsp;&nbsp;</font></div><div><font face=3D"courier new,monospace">&nbsp;&nbs=
p;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp; <strong><font color=3D"=
#ff00ff">return std::move(x);</font></strong>&nbsp;&nbsp;// should not the =
value be moved by default&nbsp;here?<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp=
;&nbsp;&nbsp; };</font></div><div>&nbsp;</div><div>I have noticed that if I=
 don't write move in the return statement, the value is copied.</div><div>S=
hould not it be moved by default? </div><div>&nbsp;</div><div>I think that =
if we capture a variable not by reference and &nbsp;its value is returned f=
rom lambda then move should be</div><div>performed by default. In the above=
 example, it should&nbsp;be enough to write:</div><div><strong></strong>&nb=
sp;</div><div><strong>&nbsp;return x;</strong></div><div><br>&nbsp;</div></=
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 />

------=_Part_454_2810726.1388167113622--

.


Author: Ville Voutilainen <ville.voutilainen@gmail.com>
Date: Fri, 27 Dec 2013 20:06:54 +0200
Raw View
On 27 December 2013 19:58, Mikhail Semenov <mikhailsemenov1957@gmail.com> wrote:
> I have looked at the following code (A is the type of x and y):
>
>                     auto f1 = [x = std::move(x),&y]() mutable ->A
>          {
>             // some processing
>             std::size_t n = x.size();
>             for (std::size_t i = 0; i < n; i++)
>                 x[i] += y[i];
>             // end some processing
>
>             return std::move(x);  // should not the value be moved by
> default here?

No, because x is not a function argument or a local variable, so the special
overload resolution rule for return doesn't kick in.

> I think that if we capture a variable not by reference and  its value is
> returned from lambda then move should be
> performed by default. In the above example, it should be enough to write:
>
>  return x;


Two ways forward:
1) write a paper
2) tell me to open an EWG issue to handle this

--

---
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/.

.


Author: Richard Smith <richard@metafoo.co.uk>
Date: Fri, 27 Dec 2013 10:40:51 -0800
Raw View
--001a1133c66cf3662904ee886eb9
Content-Type: text/plain; charset=ISO-8859-1

On 27 Dec 2013 17:58, "Mikhail Semenov" <mikhailsemenov1957@gmail.com>
wrote:
>
> I have looked at the following code (A is the type of x and y):
>
>                     auto f1 = [x = std::move(x),&y]() mutable ->A
>          {
>             // some processing
>             std::size_t n = x.size();
>             for (std::size_t i = 0; i < n; i++)
>                 x[i] += y[i];
>             // end some processing
>
>             return std::move(x);  // should not the value be moved by
default here?
>          };
>
> I have noticed that if I don't write move in the return statement, the
value is copied.
> Should not it be moved by default?

No, it should not.

> I think that if we capture a variable not by reference and  its value is
returned from lambda then move should be
> performed by default.

This seems like a bad idea. The lambda could be called more than once.

> In the above example, it should be enough to write:
>
>  return x;
>
>
>
> --
>
> ---
> 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/.

--001a1133c66cf3662904ee886eb9
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<p dir=3D"ltr"><br>
On 27 Dec 2013 17:58, &quot;Mikhail Semenov&quot; &lt;<a href=3D"mailto:mik=
hailsemenov1957@gmail.com">mikhailsemenov1957@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt; I have looked at the following code (A is the type of x and y):<br>
&gt; =A0<br>
&gt; =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 auto f1 =3D =
[x =3D std::move(x),&amp;y]() mutable -&gt;A<br>
&gt; =A0=A0=A0=A0=A0=A0=A0=A0 {<br>
&gt; =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 // some processing<br>
&gt; =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 std::size_t n =3D x.size();<br>
&gt; =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 for (std::size_t i =3D 0; i &lt; n; =
i++)<br>
&gt; =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 x[i] +=3D y[i];<br>
&gt; =A0=A0=A0=A0=A0=A0=A0=A0=A0=A0=A0 // end some processing<br>
&gt; =A0=A0=A0=A0=A0=A0=A0=A0=A0<br>
&gt; =A0=A0=A0=A0=A0=A0=A0=A0 =A0=A0 return std::move(x);=A0=A0// should no=
t the value be moved by default=A0here?<br>
&gt; =A0=A0=A0=A0=A0=A0=A0=A0 };<br>
&gt; =A0<br>
&gt; I have noticed that if I don&#39;t write move in the return statement,=
 the value is copied.<br>
&gt; Should not it be moved by default?</p>
<p dir=3D"ltr">No, it should not.<br>
 =A0<br>
&gt; I think that if we capture a variable not by reference and =A0its valu=
e is returned from lambda then move should be<br>
&gt; performed by default.</p>
<p dir=3D"ltr">This seems like a bad idea. The lambda could be called more =
than once.</p>
<p dir=3D"ltr">&gt; In the above example, it should=A0be enough to write:<b=
r>
&gt; =A0<br>
&gt; =A0return x;<br>
&gt;<br>
&gt; =A0<br>
&gt;<br>
&gt; -- <br>
&gt; =A0<br>
&gt; --- <br>
&gt; You received this message because you are subscribed to the Google Gro=
ups &quot;ISO C++ Standard - Future Proposals&quot; group.<br>
&gt; To unsubscribe from this group and stop receiving emails from it, send=
 an email to <a href=3D"mailto:std-proposals%2Bunsubscribe@isocpp.org">std-=
proposals+unsubscribe@isocpp.org</a>.<br>
&gt; To post to this group, send email to <a href=3D"mailto:std-proposals@i=
socpp.org">std-proposals@isocpp.org</a>.<br>
&gt; Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/g=
roup/std-proposals/">http://groups.google.com/a/isocpp.org/group/std-propos=
als/</a>.<br>
</p>

<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 />

--001a1133c66cf3662904ee886eb9--

.


Author: Cassio Neri <cassio.neri@gmail.com>
Date: Fri, 27 Dec 2013 10:45:16 -0800 (PST)
Raw View
------=_Part_4332_7573517.1388169916388
Content-Type: text/plain; charset=ISO-8859-1



On Friday, December 27, 2013 3:58:33 PM UTC-2, Mikhail Semenov wrote:
>
> I have looked at the following code (A is the type of x and y):
>
>                     auto f1 = [x = std::move(x),&y]() mutable ->A
>          {
>             // some processing
>             *return std::move(x);*  // should not the value be moved by
> default here?
>          };
>

No, as Ville has explained.

In addition, I disagree that an implicit move would be a good idea in this
case because users can call f1 more than once and expect, at each time,
to get the same result:

auto x1 = f1();
auto x2 = f1();

If f1.x is implicitly moved, then (likely) x1 != x2. (Of course, the user
could do:

auto x1 = f1();
auto x2 = x1;

but still!)

Giving away onwership of an object that can still be used (like f1 and f1.x)
should be made explicitly by the programmer instead of implicitly by the
compiler.

A special rule in this sense could be useful if the lambda itself was an
xvalue but additional constraints must hold. For instance the lambda should
not be returned otherwise, we're back to square one:

auto foo() {
  A x, y ; // as before
  auto f1 = ... // as before
  return f1;
}

auto f2 = foo();
auto x1 = f2();
auto x2 = f2();

--

---
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/.

------=_Part_4332_7573517.1388169916388
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br><br>On Friday, December 27, 2013 3:58:33 PM UTC-2, Mik=
hail Semenov wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;mar=
gin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><div dir=3D=
"ltr"><div>I have looked at the following code (A is the type of x and y):<=
/div><div>&nbsp;</div><div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;=
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <font fa=
ce=3D"courier new,monospace">auto f1 =3D [x =3D std::move(x),&amp;y]() muta=
ble -&gt;A<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br>&nbsp;&=
nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // some process=
ing&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br></font></div><div><=
font face=3D"courier new,monospace">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nb=
sp;&nbsp; &nbsp;&nbsp; <b><font color=3D"#ff00ff">return std::move(x);</fon=
t></b>&nbsp;&nbsp;// should not the value be moved by default&nbsp;here?<br=
>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };</font> <br></div></div=
></blockquote><div><br>No, as Ville has explained.<br><br>In addition, I di=
sagree that an implicit move would be a good idea in this<br>case because u=
sers can call f1 more than once and expect, at each time,<br>to get the sam=
e result:<br><br>auto x1 =3D f1();<br>auto x2 =3D f1();<br><br>If f1.x is i=
mplicitly moved, then (likely) x1 !=3D x2. (Of course, the user<br>could do=
:<br><br>auto x1 =3D f1();<br>auto x2 =3D x1;<br><br>but still!)<br><br>Giv=
ing away onwership of an object that can still be used (like f1 and f1.x)<b=
r>should be made explicitly by the programmer instead of implicitly by the<=
br>compiler.<br><br>A special rule in this sense could be useful if the lam=
bda itself was an<br>xvalue but additional constraints must hold. For insta=
nce the lambda should<br>not be returned otherwise, we're back to square on=
e:<br><br>auto foo() {<br>&nbsp; A x, y ; // as before<br>&nbsp; auto f1 =
=3D ... // as before<br>&nbsp; return f1;<br>}<br><br>auto f2 =3D foo();<br=
>auto x1 =3D f2();<br>auto x2 =3D f2();<br><br></div></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 />

------=_Part_4332_7573517.1388169916388--

.