Topic: Any plans for enabling the use of move-only


Author: Jeffrey Yasskin <jyasskin@google.com>
Date: Thu, 6 Feb 2014 10:28:16 -0800
Raw View
There's definitely a need for this, since right now std::function
can't be used to pass a std::packaged_task to another thread for
execution. Someone needs to write a paper to explore the design space
a bit. e.g. is it better to have std::function automatically create a
refcounted wrapper for move-only types? Or should there be a separate
move-only-function object? Or a refcounted-callable wrapper than can
then be placed into a std::function?

On Thu, Feb 6, 2014 at 9:45 AM, Scott Prager <splinterofchaos@gmail.com> wrote:
> Before generic lambdas were introduced, any `std::function` could take any
> lambda given to it, but now that lambdas have the init-capture feature, this
> is no longer true.
>
> This is being discussed on stack overflow
> (http://stackoverflow.com/questions/20843271/passing-a-non-copyable-closure-object-to-stdfunction-parameter),
> using this code example:
>
>
>     #include <iostream>
>     #include <memory>
>
>     void doit(std::function<void()> f) {
>         f();
>     }
>
>      int main()
>     {
>         std::unique_ptr<int> p(new int(5));
>         doit([p = std::move(p)] () { std::cout << *p << std::endl; });
>     }
>
>
>
> I was curious what the members of this forum might have to say, too. I did
> find an old thread from 2011, but maybe something has changed.
> (https://groups.google.com/forum/#!topic/comp.lang.c++.moderated/OFAMx695NJg)
>
> The conclusion seems that because std::function must be CopyConstructable,
> its inputs must be as well since the std::function contains its inputs. At
> first, I wondered why std::function couldn't point to a shared function
> object, but then I realized that the fallowing might lead to unexpected
> behavior:
>
>     function<int()> f = some_stateful_functor;
>     function<int()> g = f;
>     assert( f() == g() ); // May fail because result may depend on internal
> state.
>
> The solutions given, both on SO and the old thread, is to implement a
> copyable wrapper that points to the non-copyable functor, or a function
> object that throws an exception on copy. It probably works (I haven't tested
> it), but makes me uncomfortable for a couple reasons:
>
> Limits the usefulness of std::function. Incompatible with lambdas that hold
> std:: types like unique_ptr or future.
> People using lambdas may not necessarily be familiar with writing function
> objects, which may inhibit their ability to write a work-a-round.
> if this was prolific enough of a problem with lambdas to warrant a language
> extension, I expect this to be that much of a problem with std::function,
> especially now that we have init-capture.
>
> Has anything like a shared_function ever been discussed/proposed? As far as
> I can tell, the CopyConstructable requirement of std::function seems to have
> been accepted as a fact of life.
>
> --
>
> ---
> 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/.

.


Author: Nevin Liber <nevin@eviloverlord.com>
Date: Thu, 6 Feb 2014 12:33:26 -0600
Raw View
--001a11c25a9c4f286504f1c11eaa
Content-Type: text/plain; charset=ISO-8859-1

On 6 February 2014 12:28, Jeffrey Yasskin <jyasskin@google.com> wrote:

> Someone needs to write a paper to explore the design space
> a bit. e.g. is it better to have std::function automatically create a
> refcounted wrapper for move-only types? Or should there be a separate
> move-only-function object? Or a refcounted-callable wrapper than can
> then be placed into a std::function?
>

Or a throwing wrapper if an attempt is made to copy a move-only functor?

Just adding to the design space,
--
 Nevin ":-)" Liber  <mailto:nevin@eviloverlord.com>  (847) 691-1404

--

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

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

<div dir=3D"ltr">On 6 February 2014 12:28, Jeffrey Yasskin <span dir=3D"ltr=
">&lt;<a href=3D"mailto:jyasskin@google.com" target=3D"_blank">jyasskin@goo=
gle.com</a>&gt;</span> wrote:<br><div class=3D"gmail_extra"><div class=3D"g=
mail_quote">

<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">Someone needs to write a paper to explore th=
e design space<br>
a bit. e.g. is it better to have std::function automatically create a<br>
refcounted wrapper for move-only types? Or should there be a separate<br>
move-only-function object? Or a refcounted-callable wrapper than can<br>
then be placed into a std::function?<br></blockquote><div><br></div><div>Or=
 a throwing wrapper if an attempt is made to copy a move-only functor?<br><=
br></div><div>Just adding to the design space, <br></div></div>-- <br>

=A0Nevin &quot;:-)&quot; Liber=A0 &lt;mailto:<a href=3D"mailto:nevin@evilov=
erlord.com" target=3D"_blank">nevin@eviloverlord.com</a>&gt;=A0 (847) 691-1=
404
</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 />

--001a11c25a9c4f286504f1c11eaa--

.


Author: Scott Prager <splinterofchaos@gmail.com>
Date: Thu, 6 Feb 2014 11:15:29 -0800 (PST)
Raw View
------=_Part_805_2644126.1391714129542
Content-Type: text/plain; charset=UTF-8


On Thursday, February 6, 2014 1:28:16 PM UTC-5, Jeffrey Yasskin wrote:
>
> is it better to have std::function automatically create a
> refcounted wrapper for move-only types? Or should there be a separate
> move-only-function object? Or a refcounted-callable wrapper than can
> then be placed into a std::function?
>

I had a few thoughts about this but forgot to post some of them. Given my
example...


> On Thu, Feb 6, 2014 at 9:45 AM, Scott Prager <splinte...@gmail.com<javascript:>>
> wrote:
> > At
> > first, I wondered why std::function couldn't point to a shared function
> > object, but then I realized that the fallowing might lead to unexpected
> > behavior:
> >
> >     function<int()> f = some_stateful_functor;
> >     function<int()> g = f;
> >     assert( f() == g() ); // May fail because result may depend on
> internal
> > state.
>

Letting std::function point to a shared functor by default might lead to
unexpected behavior. Also, this would further impact the efficiency of
std::function, which is already much slower than passing functions without
a wrapper. Making it shared when the type is move-only would be
inconsistent. *(f() == g() IFF they are initialized with a copyable
functor.)* This is
why I asked if anyone had proposed a shared_function, specifically.
f()==g() might lead to undefined behavior at that point because the state
might
change twice between the sequence points, but at least it wouldn't be
unexpected.

Also, there may be use cases for a shared_function for when one actually
wants a
singular state, consistent across all copies.
(For example: a function that caches its results.)

One thing I thought of since my initial post was that std::future has a
member,
share(), that produces a shared_future. To clarify, when I wrote
"shared_function",
I was thinking of a function that produces an std::function using a
wrapper, though
that would seem inconsistent in terms of API design. At the same time, I
would
probably be tempted to use a shared_function (type) in every single instance
that I used an std::function, just in case. If I didn't do that, I'd need
to overload
every function I write for std::function for shared_function, but the
textual implementation would be no different in each case.


On Thursday, February 6, 2014 1:33:26 PM UTC-5, Nevin ":-)" Liber wrote:
>
> Or a throwing wrapper if an attempt is made to copy a move-only functor?
>
> Just adding to the design space,
> --
>  Nevin ":-)" Liber  <mailto:ne...@eviloverlord.com>  (847) 691-1404
>

Similarly, move_only_function?

Gosh, I feel like a loud-mouth right now. I don't mean to come across as an
expert. I'm just opinionated.

--

---
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_805_2644126.1391714129542
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><br>On Thursday, February 6, 2014 1:28:16 PM UTC-5, Jeffre=
y Yasskin wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin=
-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">is it better t=
o have std::function automatically create a
<br>refcounted wrapper for move-only types? Or should there be a separate
<br>move-only-function object? Or a refcounted-callable wrapper than can
<br>then be placed into a std::function?
<br></blockquote><div>&nbsp;</div><div>I had a few thoughts about this but =
forgot to post some of them. Given my example...<br>&nbsp;</div><blockquote=
 class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1=
px #ccc solid;padding-left: 1ex;">On Thu, Feb 6, 2014 at 9:45 AM, Scott Pra=
ger &lt;<a href=3D"javascript:" target=3D"_blank" gdf-obfuscated-mailto=3D"=
yWRlYX8SoqsJ" onmousedown=3D"this.href=3D'javascript:';return true;" onclic=
k=3D"this.href=3D'javascript:';return true;">splinte...@gmail.com</a>&gt; w=
rote:
<br>&gt; At
<br>&gt; first, I wondered why std::function couldn't point to a shared fun=
ction
<br>&gt; object, but then I realized that the fallowing might lead to unexp=
ected
<br>&gt; behavior:
<br>&gt;
<br>&gt; &nbsp; &nbsp; function&lt;int()&gt; f =3D some_stateful_functor;
<br>&gt; &nbsp; &nbsp; function&lt;int()&gt; g =3D f;
<br>&gt; &nbsp; &nbsp; assert( f() =3D=3D g() ); // May fail because result=
 may depend on internal
<br>&gt; state.
<br></blockquote><div><br><div style=3D"text-align: left;">Letting std::fun=
ction point to a shared functor by default might lead to <br>unexpected beh=
avior. Also, this would further impact the efficiency of <br>std::function,=
 which is already much slower than passing functions without <br>a wrapper.=
 Making it shared when the type is move-only would be <br>inconsistent. <i>=
(f() =3D=3D g() IFF they are initialized with a copyable functor.)</i> This=
 is <br>why I asked if anyone had proposed a shared_function, specifically.=
<br>f()=3D=3Dg() might lead to undefined behavior at that point because the=
 state might <br>change twice between the sequence points, but at least it =
wouldn't be unexpected.<br><br>Also, there may be use cases for a shared_fu=
nction for when one actually wants a <br>singular state, consistent across =
all copies. <br>(For example: a function that caches its results.)<br><br>O=
ne thing I thought of since my initial post was that std::future has a memb=
er,<br>share(), that produces a shared_future. To clarify, when I wrote "sh=
ared_function",<br>I was thinking of a function that produces an std::funct=
ion using a wrapper, though<br>that would seem inconsistent in terms of API=
 design. At the same time, I would<br>probably be tempted to use a shared_f=
unction (type) in every single instance<br>that I used an std::function, ju=
st in case. If I didn't do that, I'd need to overload<br>every function I w=
rite for std::function for shared_function, but the <br>textual implementat=
ion would be no different in each case.<br></div><br><br>On Thursday, Febru=
ary 6, 2014 1:33:26 PM UTC-5, Nevin ":-)" Liber wrote:<blockquote class=3D"=
gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc so=
lid;padding-left: 1ex;"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><d=
iv>Or a throwing wrapper if an attempt is made to copy a move-only functor?=
<br><br></div><div>Just adding to the design space, <br></div></div>-- <br>

&nbsp;Nevin ":-)" Liber&nbsp; &lt;mailto:<a target=3D"_blank">ne...@evilove=
rlord.com</a><wbr>&gt;&nbsp; (847) 691-1404
</div></div>
</blockquote><br>Similarly, move_only_function?<br><br>Gosh, I feel like a =
loud-mouth right now. I don't mean to come across as an<br>expert. I'm just=
 opinionated.<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_805_2644126.1391714129542--

.


Author: Roman Perepelitsa <roman.perepelitsa@gmail.com>
Date: Thu, 6 Feb 2014 20:31:44 +0100
Raw View
--089e012942329c881b04f1c1ed9c
Content-Type: text/plain; charset=ISO-8859-1

2014-02-06 Scott Prager <splinterofchaos@gmail.com>:

>
> On Thursday, February 6, 2014 1:33:26 PM UTC-5, Nevin ":-)" Liber wrote:
>
>> Or a throwing wrapper if an attempt is made to copy a move-only functor?
>>
>> Just adding to the design space,
>> --
>>  Nevin ":-)" Liber  <mailto:ne...@eviloverlord.com>  (847) 691-1404
>>
>
> Similarly, move_only_function?
>

That is my preferred solution and that's what I use in my code: I have
class template mfunction<F> which is exactly the same as std::function<F>
but not copyable (it's movable, though). By giving up the ability to copy
type erased functor you allow it to be constructed from non-copyable
function objects. That's a great trade off. I found the necessity to copy
std::function to be very rare, thus mfunction can be used in the vast
majority of interfaces.

Roman Perepelitsa.

--

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

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

<div dir=3D"ltr"><div class=3D"gmail_extra"><div class=3D"gmail_quote">2014=
-02-06 Scott Prager <span dir=3D"ltr">&lt;<a href=3D"mailto:splinterofchaos=
@gmail.com" target=3D"_blank">splinterofchaos@gmail.com</a>&gt;</span>:<br>=
<blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
x #ccc solid;padding-left:1ex">

<div dir=3D"ltr"><div class=3D"im"><br></div><div><div class=3D"im">On Thur=
sday, February 6, 2014 1:33:26 PM UTC-5, Nevin &quot;:-)&quot; Liber wrote:=
</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"><div><div class=3D"im"><div class=3D"gmail_quote"><div>Or =
a throwing wrapper if an attempt is made to copy a move-only functor?<br><b=
r></div><div>Just adding to the design space, <br></div></div>-- <br></div>

=A0Nevin &quot;:-)&quot; Liber=A0 &lt;mailto:<a>ne...@eviloverlord.com</a><=
u></u>&gt;=A0 (847) 691-1404
</div></div>
</blockquote><br>Similarly, move_only_function?<br></div></div></blockquote=
><div><br></div><div>That is my preferred solution and that&#39;s what I us=
e in my code: I have class template mfunction&lt;F&gt; which is exactly the=
 same as std::function&lt;F&gt; but not copyable (it&#39;s movable, though)=
.. By giving up the ability to copy type erased functor you allow it to be c=
onstructed from non-copyable function objects. That&#39;s a great trade off=
.. I found the necessity to copy std::function to be very rare, thus mfuncti=
on can be used in the vast majority of interfaces.</div>

<div><br></div><div>Roman Perepelitsa.</div></div></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 />

--089e012942329c881b04f1c1ed9c--

.