Topic: Any plans for enabling the use of move-only objects
Author: Scott Prager <splinterofchaos@gmail.com>
Date: Thu, 6 Feb 2014 09:45:22 -0800 (PST)
Raw View
------=_Part_518_12807754.1391708722868
Content-Type: text/plain; charset=UTF-8
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:
1. Limits the usefulness of std::function. Incompatible with lambdas
that hold std:: types like unique_ptr or future.
2. People using lambdas may not necessarily be familiar with writing
function objects, which may inhibit their ability to write a work-a-round.
3. 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/.
------=_Part_518_12807754.1391708722868
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Before generic lambdas were introduced, any `std::function=
` could take any lambda given to it, but now that lambdas have the init-cap=
ture feature, this is no longer true.<br><br>This is being discussed on sta=
ck overflow (<a href=3D"http://stackoverflow.com/questions/20843271/passing=
-a-non-copyable-closure-object-to-stdfunction-parameter">http://stackoverfl=
ow.com/questions/20843271/passing-a-non-copyable-closure-object-to-stdfunct=
ion-parameter</a>), using this code example:<br><pre style=3D"" class=3D"la=
ng-cpp prettyprint prettyprinted"><code><span class=3D"typ"></span></code><=
br> #include <iostream> <br> #include <memory> <br> <b=
r> void doit(std::function<void()> f) { <br> f(); <br> }=
<br><br> int main() <br> { <br> std::unique_ptr<int> p(=
new int(5)); <br> doit([p =3D std::move(p)] () { std::cout << =
*p << std::endl; }); <br> }</pre><br><br>I was curious what the me=
mbers of this forum might have to say, too. I did find an old thread from 2=
011, but maybe something has changed. (<a href=3D"https://groups.google.com=
/forum/#!topic/comp.lang.c++.moderated/OFAMx695NJg">https://groups.google.c=
om/forum/#!topic/comp.lang.c++.moderated/OFAMx695NJg</a>) <br><br>The concl=
usion seems that because std::function must be CopyConstructable, its input=
s 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:<br><b=
r> function<int()> f =3D some_stateful_functor;<br>=
function<int()> g =3D f;<br> ass=
ert( f() =3D=3D g() ); // May fail because result may depend on internal st=
ate.<br><br>The solutions given, both on SO and the old thread, is to imple=
ment a copyable wrapper that points to the non-copyable functor, or a funct=
ion object that throws an exception on copy. It probably works (I haven't t=
ested it), but makes me uncomfortable for a couple reasons: <br><ol><li>Lim=
its the usefulness of std::function. Incompatible with lambdas that hold st=
d:: types like unique_ptr or future.</li><li>People using lambdas may not n=
ecessarily be familiar with writing function objects, which may inhibit the=
ir ability to write a work-a-round.<br></li><li>if this was prolific enough=
of a problem with lambdas to warrant a language extension, I expect this t=
o be that much of a problem with std::function, especially now that we have=
init-capture.</li></ol><p>Has anything like a shared_function ever been di=
scussed/proposed? As far as I can tell, the CopyConstructable requirement o=
f std::function seems to have been accepted as a fact of life.<br></p></div=
>
<p></p>
-- <br />
<br />
--- <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 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_518_12807754.1391708722868--
.