Topic: The need for std::unique_function
Author: Ryan McDougall <mcdougall.ryan@gmail.com>
Date: Mon, 22 Oct 2018 11:18:46 -0700
Raw View
--000000000000717da90578d549c9
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
=E2=80=9CThis is motivated by increasing usage of things like executors and=
the task
queue where it is useful to embed move-only types like a std::promise withi=
n
a type erased function. That isn't possible without this version of a type
erased function.=E2=80=9D -- Chandler Carruth[1]
Thanks
=E2=80=9Cstd::function and Beyond=E2=80=9C N4159
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf>,
=E2=80=9CQualified std::function Signatures=E2=80=9D P0045R1
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf>, and
=E2=80=9CA polymorphic wrapper for all Callable objects (rev. 3)=E2=80=9D P=
0288R1
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0288r1.pdf> et
al. for laying the groundwork for this paper. Thank you to David Krauss and
Arthur O=E2=80=99Dwyer for your discussion and feedback. Thank you all auth=
ors of
alternative type erased callable containers for your proof and inspiration.
Motivation
std::function models both CopyConstructible and CopyAssignable, and
requires its erased target type to declare a copy constructor. This means
std::function is hopelessly incompatible with std::unique_ptr,
std::promise, or any other move-only type. This is a functional gap felt by
C++ users to the degree that there=E2=80=99s some half-dozen popular and
high-quality implementations available under the name =E2=80=9Cunique_funct=
ion=E2=80=9D.
[2][3][4][5][6]
C++ has many move-only vocabulary types, and when introduced they impose
tighter constraints on the interface, and can become =E2=80=9Cviral=E2=80=
=9D -- causing any
previously copyable paths to require move or forwarding operations. Conside=
r
class DbResult {
private:
std::unique_ptr<Blob> data_; // now required!
};
class Reactor {
private:
std::map<std::string, std::function<void()>> reactions_;
};
reactor.on_event(=E2=80=9Cdb-result-ready=E2=80=9D, [&] {
reactor.on_event(=E2=80=9Chas-towel=E2=80=9D, [result =3D std::move(db.res=
ult())] {
auto meaning =3D find(result); // 42
});
});
It is not enough to simply std::move the DbResult into the lambda, as
Reactor::on_event is unable to assign to a move-only lambda as implemented
with std::function.
This is a recurring pattern in much concurrent code, such as work queues,
task graphs, or command buffers. The committee implicitly understood the
need when it created std::packaged_task, also a type-erased polymorphic
container, but that type is tightly bound to std::futures, which may not be
fit for purpose in any code base that doesn=E2=80=99t already rely on them.
If we are developing any kind of asynchronous work queue we need
1.
inheritance based polymorphism (and a mechanism to manage heap allocated
derived objects, such as std::shared_ptr)
2.
type-erased container with small object optimization like std::function
(for copy-only callable types), std::packaged_task+std::future (for
move-only callable types)
However if any facet of our runtime precludes use of std::future -- such as
if it provides its own future type, or does not use futures at all, we are
again left without the ability to use std::unique_ptr or any other
non-copyable type.
auto unique =3D
std::make_unique<BankTransfer>(=E2=80=9CDrEvil=E2=80=9D, 1000000000);
auto do_bank_transfer =3D
[transfer =3D std::move(unique)] (Bank* to, Bank* from) {
return from->send(transfer, to);
};
ThreadSafeQueue<std::function<int()>> transactions1;
transactions1.emplace(do_bank_transfer); // Compile Error!!
// ...
ThreadSafeQueue<std::packaged_task<int()>> transactions2;
ThreadSafeQueue<int> results
transactions2.emplace(do_bank_transfer);
hpy::async([&] {
while (!transactions2.empty()) {
transactions2.top()();
results.push_back(transactions2.top().get_future()); // ??
}
});
In the above example we simply present wasted human time and computational
time due to an unnecessary synchronization with std::future, however a more
complex system may indeed need their own future implementation which
std::packaged_task cannot interoperate with at all.
Comparison Table
std::promise<Foo> p;
std::unique_ptr<Foo> f;
std::queue<std::function<void()>> a;
std::queue<std::unique_function<void()>> b;
using namespace std;
Before Proposal
After Proposal
1
auto s =3D make_shared<Foo>(move(f));
a.emplace([s] { s->work(); });
// ...
auto shared =3D a.top();
shared();
b.emplace([u =3D move(f)] {
u->work();
});
// ...
auto unique =3D move(b.top());
unique();
2
a.emplace([r =3D f.get()] {
r->work();
});
b.emplace([u =3D move(f)] {
u->work();
});
3
atomic<Foo*> result{nullptr};
a.emplace([&result] {
result =3D new Foo;
});
// ...
spin_on(result);
result->work();
auto future =3D p.get_future();
b.emplace([p =3D move(p)] {
p.set_value(Foo{});
});
// ...
future.get().work();
As you can see, attempts to work around the limitation of std::function
results in unacceptable undermining of uniqueness semantics, life-time
safety, and/or ease of use:
1.
Loss of move-only semantics and extra LoC and a heap allocation per
shared pointer.
2.
Queue lifetime must not exceed enclosing scope lifetime (or dangling
pointer).
3.
Poor usability or unnecessary complexity in search of better performance=
..
Alternatives
Papers =E2=80=9Cstd::function and Beyond=E2=80=9C N4159
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf>, =E2=80=
=9CA
polymorphic wrapper for all Callable objects (rev. 3)=E2=80=9D P0288R1
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0288r1.pdf> have
already argued for fixing std::function to support non-copyable types
(among other issues) some time ago. Yet it seems self evident that as long
and as widely as std::function has been in use, any change that breaks the
observable surface area of std::function is a non-starter. The question is
would the use case we outlined herein, if overlaid onto the existing
std::function, cause previously valid code to break, or conversely
previously incorrect code to become easily written?
Let=E2=80=99s assume we have a means of =E2=80=9Cfixing=E2=80=9D std::funct=
ion to allow mixing of
copy and move semantics. Clearly all existing code would continue to
function as all existing target callable types are CopyConstructible and
CopyAssignable, but what if we mix erased instances with copy and move
semantics? How should the following operations on std::function be defined
in terms of their target callable types?
Let=E2=80=99s temporarily ignore the details of memory management, and cons=
ider p
to be the underlying pointer to the erased instance.
std2::function<void()> c =3D C{}; // Copy-only
std2::function<void()> m =3D M{}; // Move-only
Operation
Definition
Result
c =3D std::move(m);
*((M*)c.p) =3D move(*((M*)m.p));
Move
m =3D std::move(c);
*((C*)c.p) =3D move(*((C*)m.p));
Copy
c =3D m;
*((M*)c.p) =3D *((M*)m.p);
Throw ???
m =3D c;
*((C*)c.p) =3D *((C*)m.p);
Copy
Again we face an unacceptable undermining of uniqueness semantics; in
addition we have changed the observable surface area of assignment by
necessitating a new runtime error reporting mechanism for when erased
targets conflicting behavior, affecting the exception-safety of existing
code.
Shallow v. Deep Const
=E2=80=9CShallow=E2=80=9D or =E2=80=9CDeep=E2=80=9D const in a type erased =
context means whether the
constness of the erasing type is extended towards the erased type. For our
discussion we consider whether the the erasing container is const callable
if and only if the underlying type is const callable.
It is by now understood that the standard requires const correctness to
imply thread-safety, and if the container operator() is const, the
underlying callable type=E2=80=99s operator() must also be const in order t=
o hope
of satisfying this obligation. So a shallow const container could not admit
a thread-safe call operation in general, and both N4159
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf> and
P0045R1
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf> draw
attention to the unfortunate outcome. The solution presented in those
papers it to include the constness of the callable in signature, and to
have the constness of container operator() be conditional on the signature.
struct Accessor {
void operator()() const;
// ...
} access;
struct Mutator {
void operator()();
// ...
} mutate;
std3::function<void() const> a =3D access; // ok
std3::function<void()> b =3D access; // ok
std3::function<void()> c =3D mutate; // ok
std3::function<void() const> d =3D mutate; // compile error
a =3D b; // compile error: target type more restrictive
b =3D a; // ok
b =3D c; // ok
This proposal, while in the author=E2=80=99s opinion is highly recommended
improvement, it=E2=80=99s best presented in referenced papers, and for simp=
licity=E2=80=99s
sake isn=E2=80=99t pursued further here.
Otherwise, without the above but desiring deep const semantics, we would
wish that const containers require const callable targets. However, since
we have erase the constness of target instance, we are left with throwing
when deep const is violated, breaking existing exception-safe code.
const std4::function<void()> a; // deep const
std::function<void()> b =3D mutate; // non-const target
a =3D b; // target copied
a(); // now throws!
Necessity and Cost
We can all agree type erased containers should support as much as feasible
the const correctness of its target types, but we began our argument with a
specific asynchronous use case that involved deferred computations, often
invoked on foreign threads. If this pattern as seen =E2=80=9Cin the wild=E2=
=80=9D makes use
of thread safe queues, is thread safety of the container itself actually
sufficient to justify the costs associated with extra synchronization or
exception safety? Even if we can guarantee const container only calls const
target methods, we still cannot guarantee the target itself makes the
connection between const and thread safety.
Should a proposed std::unique_function emulate =E2=80=9Cbroken=E2=80=9D sha=
llow const
correctness of std::function for uniformity, or is =E2=80=9Cfixing=E2=80=9D=
the
contradiction worth breaking runtime changes? And is std::unique_/function
more like a container or pointer (where const is understood to be shallow),
or is it more like an opaque type (where const is generally considered to
be deep)? Historically we allow container const to vary independently of
parameterized types when they exist, suggesting std::function should remain
a shallow container.
While this question is relevant to the specification of
std::unique_function, it is ultimately orthogonal to the question of the
need for std::unique_function to exist, which is this paper=E2=80=99s main =
concern.
Conclusion
So long as we have move-only lambdas and type erased callable containers, a
move-only capable std::function is required. As uniqueness semantics of
container are orthogonal to const-correctness of the interface we recommend
not conflating the two, and pursuing P0045R1
<http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf> for
const-correctness as an independent feature request.
References
[1] https://reviews.llvm.org/D48349
[2] http://llvm.org/doxygen/FunctionExtras_8h_source.html#l00046
[3]
https://github.com/STEllAR-GROUP/hpx/blob/master/hpx/util/unique_function.h=
pp
[4]
https://github.com/potswa/cxx_function/blob/master/cxx_function.hpp#L1192
[5]
https://github.com/Naios/function2/blob/master/include/function2/function2.=
hpp#L1406
[6] https://github.com/facebook/folly/blob/master/folly/Function.h
--=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/CAHn%2BA5NyaUQjAeudtObjn08Trz4iJ%2Bu-GGt2J5Vnmtm=
ZJiPVxg%40mail.gmail.com.
--000000000000717da90578d549c9
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><span id=3D"gmail-docs-internal-guid-def7cea7-7fff-bf6e-c2=
f3-4764896f986c"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;ma=
rgin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(=
0,0,0);background-color:transparent;font-variant-numeric:normal;font-varian=
t-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">=E2=80=9C=
This is motivated by increasing usage of things like executors and the task=
</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-b=
ottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0)=
;background-color:transparent;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap">queue where it =
is useful to embed move-only types like a std::promise within</span></p><p =
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><sp=
an style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-co=
lor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;=
vertical-align:baseline;white-space:pre-wrap">a type erased function. That =
isn't possible without this version of a type</span></p><p dir=3D"ltr" =
style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"=
font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transpar=
ent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-ali=
gn:baseline;white-space:pre-wrap">erased function.=E2=80=9D -- Chandler Car=
ruth[1]</span></p><h1 dir=3D"ltr" style=3D"line-height:1.38;margin-top:20pt=
;margin-bottom:6pt"><span style=3D"font-size:20pt;font-family:Arial;color:r=
gb(0,0,0);background-color:transparent;font-weight:400;font-variant-numeric=
:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:=
pre-wrap">Thanks</span></h1><p dir=3D"ltr" style=3D"line-height:1.38;margin=
-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial=
;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;=
font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap=
">=E2=80=9Cstd::function and Beyond=E2=80=9C </span><a href=3D"http://www.o=
pen-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf" style=3D"text-decora=
tion-line:none"><span style=3D"font-size:11pt;font-family:Arial;background-=
color:transparent;font-variant-numeric:normal;font-variant-east-asian:norma=
l;text-decoration-line:underline;vertical-align:baseline;white-space:pre-wr=
ap">N4159</span></a><span style=3D"font-size:11pt;font-family:Arial;color:r=
gb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-var=
iant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">, =E2=
=80=9CQualified std::function Signatures=E2=80=9D </span><a href=3D"http://=
www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf" style=3D"text=
-decoration-line:none"><span style=3D"font-size:11pt;font-family:Arial;back=
ground-color:transparent;font-variant-numeric:normal;font-variant-east-asia=
n:normal;text-decoration-line:underline;vertical-align:baseline;white-space=
:pre-wrap">P0045R1</span></a><span style=3D"font-size:11pt;font-family:Aria=
l;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal=
;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wra=
p">, and =E2=80=9CA polymorphic wrapper for all Callable objects (rev. 3)=
=E2=80=9D </span><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/pap=
ers/2017/p0288r1.pdf" style=3D"text-decoration-line:none"><span style=3D"fo=
nt-size:11pt;font-family:Arial;background-color:transparent;font-variant-nu=
meric:normal;font-variant-east-asian:normal;text-decoration-line:underline;=
vertical-align:baseline;white-space:pre-wrap">P0288R1</span></a><span style=
=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap"> et al. for laying the groundwork for=
this paper. Thank you to David Krauss and Arthur O=E2=80=99Dwyer for your =
discussion and feedback. Thank you all authors of alternative type erased c=
allable containers for your proof and inspiration.</span></p><h1 dir=3D"ltr=
" style=3D"line-height:1.38;margin-top:20pt;margin-bottom:6pt"><span style=
=3D"font-size:20pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-weight:400;font-variant-numeric:normal;font-variant-east-asian=
:normal;vertical-align:baseline;white-space:pre-wrap">Motivation</span></h1=
><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"=
><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgroun=
d-color:transparent;font-variant-numeric:normal;font-variant-east-asian:nor=
mal;vertical-align:baseline;white-space:pre-wrap">std::function models both=
CopyConstructible and CopyAssignable, and requires its erased target type =
to declare a copy constructor. This means std::function =C2=A0is hopelessly=
incompatible with std::unique_ptr, std::promise, or any other move-only ty=
pe. This is a functional gap felt by C++ users to the degree that there=E2=
=80=99s some half-dozen popular and high-quality implementations available =
under the name =E2=80=9Cunique_function=E2=80=9D. [2][3][4][5][6]</span></p=
><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:=
0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backg=
round-color:transparent;font-variant-numeric:normal;font-variant-east-asian=
:normal;vertical-align:baseline;white-space:pre-wrap">C++ has many move-onl=
y vocabulary types, and when introduced they impose tighter constraints on =
the interface, and can become =E2=80=9Cviral=E2=80=9D -- causing any previo=
usly copyable paths to require move or forwarding operations. Consider</spa=
n></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bo=
ttom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New"=
;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;=
font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap=
">class DbResult {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margi=
n-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&quo=
t;Courier New";color:rgb(0,0,0);background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;w=
hite-space:pre-wrap"> private:</span></p><p dir=3D"ltr" style=3D"line-heigh=
t:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font=
-family:"Courier New";color:rgb(0,0,0);background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap"> =C2=A0std::unique_ptr<Blob> data_; =
=C2=A0// now required!</span></p><p dir=3D"ltr" style=3D"line-height:1.38;m=
argin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:=
"Courier New";color:rgb(0,0,0);background-color:transparent;font-=
variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseli=
ne;white-space:pre-wrap">};</span></p><br><p dir=3D"ltr" style=3D"line-heig=
ht:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;fon=
t-family:"Courier New";color:rgb(0,0,0);background-color:transpar=
ent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-ali=
gn:baseline;white-space:pre-wrap">class Reactor {</span></p><p dir=3D"ltr" =
style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"=
font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgro=
und-color:transparent;font-variant-numeric:normal;font-variant-east-asian:n=
ormal;vertical-align:baseline;white-space:pre-wrap"> private:</span></p><p =
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><sp=
an style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,=
0,0);background-color:transparent;font-variant-numeric:normal;font-variant-=
east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0std:=
:map<std::string, std::function<void()>> reactions_;</span></p>=
<p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt">=
<span style=3D"font-size:11pt;font-family:"Courier New";color:rgb=
(0,0,0);background-color:transparent;font-variant-numeric:normal;font-varia=
nt-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">};</span=
></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bot=
tom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";=
color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;f=
ont-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"=
>reactor.on_event(=E2=80=9Cdb-result-ready=E2=80=9D, [&] {</span></p><p=
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0rea=
ctor.on_event(=E2=80=9Chas-towel=E2=80=9D, [result =3D std::move(db.result(=
))] {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;mar=
gin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New=
";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pr=
e-wrap"> =C2=A0=C2=A0=C2=A0auto meaning =3D find(result); // 42</span></p><=
p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><=
span style=3D"font-size:11pt;font-family:"Courier New";color:rgb(=
0,0,0);background-color:transparent;font-variant-numeric:normal;font-varian=
t-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0})=
;</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">});</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0=
pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color=
:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">It i=
s not enough to simply std::move the DbResult into the lambda, as Reactor::=
on_event is unable to assign to a move-only lambda as implemented with std:=
:function.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-to=
p:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;co=
lor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fon=
t-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">T=
his is a recurring pattern in much concurrent code, such as work queues, ta=
sk graphs, or command buffers. The committee implicitly understood the need=
when it created std::packaged_task, also a type-erased polymorphic contain=
er, but that type is tightly bound to std::futures, which may not be fit fo=
r purpose in any code base that doesn=E2=80=99t already rely on them.</span=
></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bot=
tom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);b=
ackground-color:transparent;font-variant-numeric:normal;font-variant-east-a=
sian:normal;vertical-align:baseline;white-space:pre-wrap">If we are develop=
ing</span><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);=
background-color:transparent;font-style:italic;font-variant-numeric:normal;=
font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap=
"> any</span><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,=
0);background-color:transparent;font-variant-numeric:normal;font-variant-ea=
st-asian:normal;vertical-align:baseline;white-space:pre-wrap"> kind of asyn=
chronous work queue we need </span></p><ol style=3D"margin-top:0pt;margin-b=
ottom:0pt"><li dir=3D"ltr" style=3D"list-style-type:upper-alpha;font-size:1=
1pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-va=
riant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline=
;white-space:pre"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;m=
argin-bottom:0pt"><span style=3D"font-size:11pt;background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap">inheritance based polymorphism (and a mecha=
nism to manage heap allocated derived objects, such as std::shared_ptr)</sp=
an></p></li><li dir=3D"ltr" style=3D"list-style-type:upper-alpha;font-size:=
11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;=
margin-bottom:0pt"><span style=3D"font-size:11pt;background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap">type-erased container with </span><span st=
yle=3D"font-size:11pt;background-color:transparent;font-style:italic;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">small object optimization</span><span style=3D"font=
-size:11pt;background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> like=
std::function (for copy-only callable types), std::packaged_task+std::futu=
re (for move-only callable types)</span></p></li></ol><br><p dir=3D"ltr" st=
yle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"fo=
nt-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap">However if any facet of our runtime preclud=
es use of std::future -- such as if it provides its own future type, or doe=
s not use futures at all, we are again left without the ability to use std:=
:unique_ptr or </span><span style=3D"font-size:11pt;font-family:Arial;color=
:rgb(0,0,0);background-color:transparent;font-weight:700;font-style:italic;=
font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:b=
aseline;white-space:pre-wrap">any other</span><span style=3D"font-size:11pt=
;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap"> non-copyable type.</span></p><br><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:"Courier New";color:rgb(0,0,0);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">auto unique =3D</span></p><p=
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0std=
::make_unique<BankTransfer>(=E2=80=9CDrEvil=E2=80=9D, 1000000000);</s=
pan></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">auto do_bank_transfer =3D</span></p><p dir=3D"ltr" style=3D"line-height=
:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-=
family:"Courier New";color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap"> =C2=A0[transfer =3D std::move(unique)] (Ba=
nk* to, Bank* from) {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&=
quot;Courier New";color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap"> =C2=A0=C2=A0=C2=A0return from->send(transfer, t=
o);</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margi=
n-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&q=
uot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:nor=
mal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-=
wrap">};</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:=
0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Cour=
ier New";color:rgb(0,0,0);background-color:transparent;font-variant-nu=
meric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-s=
pace:pre-wrap">ThreadSafeQueue<std::function<int()>> transactio=
ns1;</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;marg=
in-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&=
quot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre=
-wrap">transactions1.emplace(do_bank_transfer); =C2=A0// Compile Error!!</s=
pan></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">// ...</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-to=
p:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Co=
urier New";color:rgb(0,0,0);background-color:transparent;font-variant-=
numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white=
-space:pre-wrap">ThreadSafeQueue<std::packaged_task<int()>> tra=
nsactions2;</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0=
pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Couri=
er New";color:rgb(0,0,0);background-color:transparent;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap">ThreadSafeQueue<int> results</span></p><p dir=3D"ltr" s=
tyle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"f=
ont-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap">transactions2.emplace(do=
_bank_transfer);</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;mar=
gin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&q=
uot;Courier New";color:rgb(0,0,0);background-color:transparent;font-va=
riant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline=
;white-space:pre-wrap">hpy::async([&] {</span></p><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:"Courier New";color:rgb(0,0,0);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap"> =C2=A0while (!transactions2=
..empty()) {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0=
pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Couri=
er New";color:rgb(0,0,0);background-color:transparent;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap"> =C2=A0=C2=A0=C2=A0transactions2.top()();</span></p><p dir=3D=
"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span sty=
le=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);b=
ackground-color:transparent;font-variant-numeric:normal;font-variant-east-a=
sian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0=C2=A0=C2=
=A0results.push_back(transactions2.top().get_future()); // ??</span></p><p =
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><sp=
an style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,=
0,0);background-color:transparent;font-variant-numeric:normal;font-variant-=
east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0}</s=
pan></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bott=
om:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";c=
olor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fo=
nt-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">=
});</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;m=
argin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb=
(0,0,0);background-color:transparent;font-variant-numeric:normal;font-varia=
nt-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">In the a=
bove example we simply present wasted human time and computational time due=
to an unnecessary synchronization with std::future, however a more complex=
system may indeed need their own future implementation which std::packaged=
_task cannot interoperate with at all.</span></p><h1 dir=3D"ltr" style=3D"l=
ine-height:1.38;margin-top:20pt;margin-bottom:6pt"><span style=3D"font-size=
:20pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-=
weight:400;font-variant-numeric:normal;font-variant-east-asian:normal;verti=
cal-align:baseline;white-space:pre-wrap">Comparison Table</span></h1><p dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span =
style=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0=
);background-color:transparent;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;vertical-align:baseline;white-space:pre-wrap">std::promise&l=
t;Foo> p;</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:=
0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Cour=
ier New";color:rgb(0,0,0);background-color:transparent;font-variant-nu=
meric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-s=
pace:pre-wrap">std::unique_ptr<Foo> f;</span></p><p dir=3D"ltr" style=
=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-s=
ize:10pt;font-family:"Courier New";color:rgb(0,0,0);background-co=
lor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;=
vertical-align:baseline;white-space:pre-wrap">std::queue<std::function&l=
t;void()>> a;</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margi=
n-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:&quo=
t;Courier New";color:rgb(0,0,0);background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;w=
hite-space:pre-wrap">std::queue<std::unique_function<void()>> b=
;</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">using namespace std;</span></p><br><div dir=3D"ltr" style=3D"margin-lef=
t:0pt"><table style=3D"border:none;border-collapse:collapse"><colgroup><col=
width=3D"17"><col width=3D"295"><col width=3D"289"></colgroup><tbody><tr s=
tyle=3D"height:0pt"><td style=3D"border-width:1pt;border-style:solid;border=
-color:rgb(0,0,0);vertical-align:top;padding:5pt"><br></td><td style=3D"bor=
der-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top=
;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin=
-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,=
0);background-color:transparent;font-variant-numeric:normal;font-variant-ea=
st-asian:normal;vertical-align:baseline;white-space:pre-wrap">Before Propos=
al</span></p></td><td style=3D"border-width:1pt;border-style:solid;border-c=
olor:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"lin=
e-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11p=
t;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;w=
hite-space:pre-wrap">After Proposal</span></p></td></tr><tr style=3D"height=
:67pt"><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,=
0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.=
2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-fami=
ly:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric=
:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:=
pre-wrap">1</span></p></td><td style=3D"border-width:1pt;border-style:solid=
;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" sty=
le=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font=
-size:10pt;font-family:"Courier New";color:rgb(0,0,0);background-=
color:transparent;font-variant-numeric:normal;font-variant-east-asian:norma=
l;vertical-align:baseline;white-space:pre-wrap">auto s =3D make_shared<F=
oo>(move(f));</span><span style=3D"font-size:10pt;font-family:"Cour=
ier New";color:rgb(0,0,0);background-color:transparent;font-variant-nu=
meric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-s=
pace:pre-wrap"><br class=3D"gmail-kix-line-break"></span><span style=3D"fon=
t-size:10pt;font-family:"Courier New";color:rgb(0,0,0);background=
-color:transparent;font-variant-numeric:normal;font-variant-east-asian:norm=
al;vertical-align:baseline;white-space:pre-wrap">a.emplace([s] { s->work=
(); });</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;ma=
rgin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier Ne=
w";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap"><br class=3D"gmail-kix-line-break"></span><span style=3D"font-size=
:10pt;font-family:"Courier New";color:rgb(0,0,0);background-color=
:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap">// ...</span></p><p dir=3D"ltr" =
style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"f=
ont-size:10pt;font-family:"Courier New";color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap">auto shared =3D a.top();=
</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bo=
ttom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New"=
;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;=
font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap=
">shared();</span></p></td><td style=3D"border-width:1pt;border-style:solid=
;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" sty=
le=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font=
-size:10pt;font-family:"Courier New";color:rgb(0,0,0);background-=
color:transparent;font-variant-numeric:normal;font-variant-east-asian:norma=
l;vertical-align:baseline;white-space:pre-wrap">b.emplace([u =3D move(f)] {=
</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bo=
ttom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New"=
;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;=
font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap=
"> =C2=A0u->work();</span></p><p dir=3D"ltr" style=3D"line-height:1.2;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:&=
quot;Courier New";color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">});</span></p><p dir=3D"ltr" style=3D"line-height:1=
..2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-fam=
ily:"Courier New";color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">// ...</span></p><p dir=3D"ltr" style=3D"line-=
height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;=
font-family:"Courier New";color:rgb(0,0,0);background-color:trans=
parent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-=
align:baseline;white-space:pre-wrap">auto unique =3D move(b.top());</span><=
/p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt=
"><span style=3D"font-size:10pt;font-family:"Courier New";color:r=
gb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-var=
iant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">unique=
();</span></p></td></tr><tr style=3D"height:0pt"><td style=3D"border-width:=
1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5=
pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0p=
t"><span style=3D"font-size:10pt;font-family:Arial;color:rgb(0,0,0);backgro=
und-color:transparent;font-variant-numeric:normal;font-variant-east-asian:n=
ormal;vertical-align:baseline;white-space:pre-wrap">2</span></p></td><td st=
yle=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical=
-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:=
0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Cour=
ier New";color:rgb(0,0,0);background-color:transparent;font-variant-nu=
meric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-s=
pace:pre-wrap">a.emplace([r =3D f.get()] {</span></p><p dir=3D"ltr" style=
=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-s=
ize:10pt;font-family:"Courier New";color:rgb(0,0,0);background-co=
lor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;=
vertical-align:baseline;white-space:pre-wrap"> =C2=A0r->work();</span></=
p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"=
><span style=3D"font-size:10pt;font-family:"Courier New";color:rg=
b(0,0,0);background-color:transparent;font-variant-numeric:normal;font-vari=
ant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">});</sp=
an></p></td><td style=3D"border-width:1pt;border-style:solid;border-color:r=
gb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-heig=
ht:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font=
-family:"Courier New";color:rgb(0,0,0);background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap">b.emplace([u =3D move(f)] {</span></p><p d=
ir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span=
style=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,=
0);background-color:transparent;font-variant-numeric:normal;font-variant-ea=
st-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0u->=
work();</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;ma=
rgin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier Ne=
w";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap">});</span></p></td></tr><tr style=3D"height:0pt"><td style=3D"bord=
er-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;=
padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:10pt;font-family:Arial;color:rgb(0,0,0=
);background-color:transparent;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;vertical-align:baseline;white-space:pre-wrap">3</span></p></=
td><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0)=
;vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:&=
quot;Courier New";color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">atomic<Foo*> result{nullptr};</span></p><p di=
r=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span =
style=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0=
);background-color:transparent;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;vertical-align:baseline;white-space:pre-wrap">a.emplace([&am=
p;result] {</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0p=
t;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courie=
r New";color:rgb(0,0,0);background-color:transparent;font-variant-nume=
ric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spa=
ce:pre-wrap"> =C2=A0result =3D new Foo;</span></p><p dir=3D"ltr" style=3D"l=
ine-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
0pt;font-family:"Courier New";color:rgb(0,0,0);background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;verti=
cal-align:baseline;white-space:pre-wrap">});</span><span style=3D"font-size=
:10pt;font-family:"Courier New";color:rgb(0,0,0);background-color=
:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap"><br class=3D"gmail-kix-line-brea=
k"></span><span style=3D"font-size:10pt;font-family:"Courier New"=
;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;=
font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap=
">// ...</span><span style=3D"font-size:10pt;font-family:"Courier New&=
quot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre=
-wrap"><br class=3D"gmail-kix-line-break"></span><span style=3D"font-size:1=
0pt;font-family:"Courier New";color:rgb(0,0,0);background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;verti=
cal-align:baseline;white-space:pre-wrap">spin_on(result);</span><span style=
=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap"><br class=3D"gmail-=
kix-line-break"></span><span style=3D"font-size:10pt;font-family:"Cour=
ier New";color:rgb(0,0,0);background-color:transparent;font-variant-nu=
meric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-s=
pace:pre-wrap">result->work();</span></p></td><td style=3D"border-width:=
1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5=
pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0p=
t"><span style=3D"font-size:10pt;font-family:"Courier New";color:=
rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">auto =
future =3D p.get_future();</span></p><p dir=3D"ltr" style=3D"line-height:1.=
2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-fami=
ly:"Courier New";color:rgb(0,0,0);background-color:transparent;fo=
nt-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:bas=
eline;white-space:pre-wrap">b.emplace([p =3D move(p)] {</span></p><p dir=3D=
"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span styl=
e=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0);ba=
ckground-color:transparent;font-variant-numeric:normal;font-variant-east-as=
ian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0p.set_value=
(Foo{});</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;m=
argin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier N=
ew";color:rgb(0,0,0);background-color:transparent;font-variant-numeric=
:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:=
pre-wrap">});</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:=
0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Cour=
ier New";color:rgb(0,0,0);background-color:transparent;font-variant-nu=
meric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-s=
pace:pre-wrap">// ...</span></p><p dir=3D"ltr" style=3D"line-height:1.2;mar=
gin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:&q=
uot;Courier New";color:rgb(0,0,0);background-color:transparent;font-va=
riant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline=
;white-space:pre-wrap">future.get().work();</span></p></td></tr></tbody></t=
able></div><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;marg=
in-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,=
0,0);background-color:transparent;font-variant-numeric:normal;font-variant-=
east-asian:normal;vertical-align:baseline;white-space:pre-wrap">As you can =
see, attempts to work around the limitation of std::function results in una=
cceptable undermining of uniqueness semantics, life-time safety, and/or eas=
e of use:</span></p><ol style=3D"margin-top:0pt;margin-bottom:0pt"><li dir=
=3D"ltr" style=3D"list-style-type:decimal;font-size:11pt;font-family:Arial;=
color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;f=
ont-variant-east-asian:normal;vertical-align:baseline;white-space:pre"><p d=
ir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><spa=
n style=3D"font-size:11pt;background-color:transparent;font-variant-numeric=
:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:=
pre-wrap">Loss of move-only semantics and extra LoC and a heap allocation p=
er shared pointer.</span></p></li><li dir=3D"ltr" style=3D"list-style-type:=
decimal;font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:=
transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vert=
ical-align:baseline;white-space:pre"><p dir=3D"ltr" style=3D"line-height:1.=
38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap">Queue lifetime must not =
exceed enclosing scope lifetime (or dangling pointer).</span></p></li><li d=
ir=3D"ltr" style=3D"list-style-type:decimal;font-size:11pt;font-family:Aria=
l;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal=
;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre"><p=
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:11pt;background-color:transparent;font-variant-numer=
ic:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spac=
e:pre-wrap">Poor usability or unnecessary complexity in search of better pe=
rformance.</span></p></li></ol><h1 dir=3D"ltr" style=3D"line-height:1.38;ma=
rgin-top:20pt;margin-bottom:6pt"><span style=3D"font-size:20pt;font-family:=
Arial;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-va=
riant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline=
;white-space:pre-wrap">Alternatives</span></h1><p dir=3D"ltr" style=3D"line=
-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11p=
t;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;w=
hite-space:pre-wrap">Papers =E2=80=9Cstd::function and Beyond=E2=80=9C </sp=
an><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159=
..pdf" style=3D"text-decoration-line:none"><span style=3D"font-size:11pt;fon=
t-family:Arial;background-color:transparent;font-variant-numeric:normal;fon=
t-variant-east-asian:normal;text-decoration-line:underline;vertical-align:b=
aseline;white-space:pre-wrap">N4159</span></a><span style=3D"font-size:11pt=
;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap">, =E2=80=9CA polymorphic wrapper for all Callable objec=
ts (rev. 3)=E2=80=9D </span><a href=3D"http://www.open-std.org/jtc1/sc22/wg=
21/docs/papers/2017/p0288r1.pdf" style=3D"text-decoration-line:none"><span =
style=3D"font-size:11pt;font-family:Arial;background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;text-decoration-line=
:underline;vertical-align:baseline;white-space:pre-wrap">P0288R1</span></a>=
<span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background=
-color:transparent;font-variant-numeric:normal;font-variant-east-asian:norm=
al;vertical-align:baseline;white-space:pre-wrap"> have already argued for f=
ixing std::function to support non-copyable types (among other issues) some=
time ago. Yet it seems self evident that as long and as widely as std::fun=
ction has been in use, any change that breaks the observable surface area o=
f std::function is a non-starter. The question is would the use case we out=
lined herein, if overlaid onto the existing std::function, cause previously=
valid code to break, or conversely previously incorrect code to become eas=
ily written?</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-=
top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;=
color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;f=
ont-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"=
>Let=E2=80=99s assume we have a means of =E2=80=9Cfixing=E2=80=9D std::func=
tion to allow mixing of copy and move semantics. Clearly all existing code =
would continue to function as all existing target callable types are CopyCo=
nstructible and CopyAssignable, but what if we mix erased instances with co=
py and move semantics? How should the following operations on std::function=
be defined in terms of their target callable types?</span></p><br><p dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span =
style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color=
:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap">Let=E2=80=99s temporarily ignore=
the details of memory management, and consider </span><span style=3D"font-=
size:11pt;font-family:"Courier New";color:rgb(0,0,0);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">p</span><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap"> to be the underlying pointer to the erased in=
stance.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0=
pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Couri=
er New";color:rgb(0,0,0);background-color:transparent;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap">std2::function<void()> c =3D C{}; // Copy-only</span><s=
pan style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class=
=3D"gmail-kix-line-break"></span><span style=3D"font-size:11pt;font-family:=
"Courier New";color:rgb(0,0,0);background-color:transparent;font-=
variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseli=
ne;white-space:pre-wrap">std2::function<void()> m =3D M{}; // Move-on=
ly</span></p><br><br><div dir=3D"ltr" style=3D"margin-left:0pt"><table styl=
e=3D"border:none;border-collapse:collapse"><colgroup><col width=3D"163"><co=
l width=3D"276"><col width=3D"166"></colgroup><tbody><tr style=3D"height:0p=
t"><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0)=
;vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;m=
argin-top:0pt;margin-bottom:0pt;text-align:center"><span style=3D"font-size=
:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-=
variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseli=
ne;white-space:pre-wrap">Operation</span></p></td><td style=3D"border-width=
:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:=
5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:=
0pt;text-align:center"><span style=3D"font-size:11pt;font-family:Arial;colo=
r:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-=
variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Def=
inition</span></p></td><td style=3D"border-width:1pt;border-style:solid;bor=
der-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt;text-align:center"><s=
pan style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">Result</span></p></td></tr><=
tr style=3D"height:0pt"><td style=3D"border-width:1pt;border-style:solid;bo=
rder-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:"Courier New";color:rgb(0,0,0);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">c =3D std::move(m);</span></=
p></td><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,=
0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.=
38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-fam=
ily:"Courier New";color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">*((M*)c.p) =3D move(*((M*)m.p));</span></p></t=
d><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);=
vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;ma=
rgin-top:0pt;margin-bottom:0pt;text-align:center"><span style=3D"font-size:=
11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">Move</span></p></td></tr><tr style=3D"height:0pt"><=
td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);ver=
tical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margi=
n-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&quo=
t;Courier New";color:rgb(0,0,0);background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;w=
hite-space:pre-wrap">m =3D std::move(c);</span></p></td><td style=3D"border=
-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;pa=
dding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-b=
ottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New"=
;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal=
;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wra=
p">*((C*)c.p) =3D move(*((C*)m.p));</span></p></td><td style=3D"border-widt=
h:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding=
:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom=
:0pt;text-align:center"><span style=3D"font-size:11pt;font-family:Arial;col=
or:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font=
-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Co=
py</span></p></td></tr><tr style=3D"height:0pt"><td style=3D"border-width:1=
pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5p=
t"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0p=
t"><span style=3D"font-size:11pt;font-family:"Courier New";color:=
rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">c =3D=
m;</span></p></td><td style=3D"border-width:1pt;border-style:solid;border-=
color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"li=
ne-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
1pt;font-family:"Courier New";color:rgb(153,153,153);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">*((M*)c.p) =3D *((M*)m.p);</=
span></p></td><td style=3D"border-width:1pt;border-style:solid;border-color=
:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-he=
ight:1.38;margin-top:0pt;margin-bottom:0pt;text-align:center"><span style=
=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap">Throw ???</span></p></td></tr><tr sty=
le=3D"height:0pt"><td style=3D"border-width:1pt;border-style:solid;border-c=
olor:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"lin=
e-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11=
pt;font-family:"Courier New";color:rgb(0,0,0);background-color:tr=
ansparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertic=
al-align:baseline;white-space:pre-wrap">m =3D c;</span></p></td><td style=
=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-al=
ign:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0p=
t;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courie=
r New";color:rgb(0,0,0);background-color:transparent;font-variant-nume=
ric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spa=
ce:pre-wrap">*((C*)c.p) =3D *((C*)m.p);</span></p></td><td style=3D"border-=
width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;pad=
ding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bo=
ttom:0pt;text-align:center"><span style=3D"font-size:11pt;font-family:Arial=
;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;=
font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap=
">Copy</span></p></td></tr></tbody></table></div><br><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">Again we face an unacceptable undermining of u=
niqueness semantics; in addition we have changed the observable surface are=
a of assignment by necessitating a new runtime error reporting mechanism fo=
r when erased targets conflicting behavior, affecting the exception-safety =
of existing code.</span></p><h2 dir=3D"ltr" style=3D"line-height:1.38;margi=
n-top:18pt;margin-bottom:6pt"><span style=3D"font-size:16pt;font-family:Ari=
al;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap">Shallow v. Deep Const</span></h2><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">=E2=80=9CShallow=E2=80=9D or =E2=80=9CDeep=E2=
=80=9D const in a type erased context means whether the constness of the er=
asing type is extended towards the erased type. For our discussion we consi=
der whether the the erasing container is const callable if and only if the =
underlying type is const callable.</span></p><p dir=3D"ltr" style=3D"line-h=
eight:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;=
font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varian=
t-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whi=
te-space:pre-wrap"><br class=3D"gmail-kix-line-break"></span><span style=3D=
"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transpa=
rent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-al=
ign:baseline;white-space:pre-wrap">It is by now understood that the standar=
d requires const correctness to imply thread-safety, and if the container o=
perator() is const, the underlying callable type=E2=80=99s operator() must =
also be const in order to </span><span style=3D"font-size:11pt;font-family:=
Arial;color:rgb(0,0,0);background-color:transparent;font-style:italic;font-=
variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseli=
ne;white-space:pre-wrap">hope</span><span style=3D"font-size:11pt;font-fami=
ly:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric=
:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:=
pre-wrap"> of satisfying this obligation. So a shallow const container coul=
d not admit a thread-safe call operation in general, and both </span><a hre=
f=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf" sty=
le=3D"text-decoration-line:none"><span style=3D"font-size:11pt;font-family:=
Arial;background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;text-decoration-line:underline;vertical-align:baseline;w=
hite-space:pre-wrap">N4159</span></a><span style=3D"font-size:11pt;font-fam=
ily:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeri=
c:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space=
:pre-wrap"> and </span><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/do=
cs/papers/2017/p0045r1.pdf" style=3D"text-decoration-line:none"><span style=
=3D"font-size:11pt;font-family:Arial;background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:unde=
rline;vertical-align:baseline;white-space:pre-wrap">P0045R1</span></a><span=
style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ve=
rtical-align:baseline;white-space:pre-wrap"> draw attention to the unfortun=
ate outcome. The solution presented in those papers it to include the const=
ness of the callable in signature, and to have the constness of container o=
perator() be conditional on the signature.</span><span style=3D"font-size:1=
1pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-va=
riant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline=
;white-space:pre-wrap"><br class=3D"gmail-kix-line-break"><br class=3D"gmai=
l-kix-line-break"></span></p><p dir=3D"ltr" style=3D"line-height:1.38;margi=
n-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&quo=
t;Courier New";color:rgb(0,0,0);background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;w=
hite-space:pre-wrap">struct Accessor {</span></p><p dir=3D"ltr" style=3D"li=
ne-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
1pt;font-family:"Courier New";color:rgb(0,0,0);background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;verti=
cal-align:baseline;white-space:pre-wrap"> =C2=A0void operator()() const;</s=
pan></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bott=
om:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";c=
olor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fo=
nt-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">=
=C2=A0// ...</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top=
:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Cou=
rier New";color:rgb(0,0,0);background-color:transparent;font-variant-n=
umeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-=
space:pre-wrap">} access;</span></p><br><p dir=3D"ltr" style=3D"line-height=
:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-=
family:"Courier New";color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap">struct Mutator {</span></p><p dir=3D"ltr" s=
tyle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"f=
ont-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0void operator()()=
;</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap"> =C2=A0// ...</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin=
-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"=
;Courier New";color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap">} mutate;</span></p><br><p dir=3D"ltr" style=3D"line-he=
ight:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;f=
ont-family:"Courier New";color:rgb(0,0,0);background-color:transp=
arent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-a=
lign:baseline;white-space:pre-wrap">std3::function<void() const> a =
=3D access; =C2=A0// ok</span></p><p dir=3D"ltr" style=3D"line-height:1.38;=
margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family=
:"Courier New";color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap">std3::function<void()> b =3D access; =C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// ok</span></p><p dir=3D"ltr" style=3D=
"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-siz=
e:11pt;font-family:"Courier New";color:rgb(0,0,0);background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ve=
rtical-align:baseline;white-space:pre-wrap">std3::function<void()> c =
=3D mutate; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// ok</span></p><p di=
r=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span=
style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,=
0);background-color:transparent;font-variant-numeric:normal;font-variant-ea=
st-asian:normal;vertical-align:baseline;white-space:pre-wrap">std3::functio=
n<void() const> d =3D mutate; =C2=A0// compile error</span></p><br><p=
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">a =3D b; =
=C2=A0// compile error: target type more restrictive</span></p><p dir=3D"lt=
r" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap">b =3D a; =C2=A0// o=
k</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">b =3D c; =C2=A0// ok</span></p><p dir=3D"ltr" style=3D"line-height:1.38=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-famil=
y:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap"><br class=3D"gmail-kix-line-break"></span><span style=3D"font-size=
:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-=
variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseli=
ne;white-space:pre-wrap">This proposal, while in the author=E2=80=99s opini=
on is highly recommended improvement, it=E2=80=99s best presented in refere=
nced papers, and for simplicity=E2=80=99s sake isn=E2=80=99t pursued furthe=
r here.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0=
pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color=
:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Othe=
rwise, without the above but desiring deep const semantics, we would wish t=
hat const containers require const callable targets. However, since we have=
erase the constness of target instance, we are left with throwing when dee=
p const is violated, breaking existing exception-safe code.</span></p><br><=
p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><=
span style=3D"font-size:11pt;font-family:"Courier New";color:rgb(=
0,0,0);background-color:transparent;font-variant-numeric:normal;font-varian=
t-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">const std=
4::function<void()> a; =C2=A0=C2=A0=C2=A0// deep const</span></p><p d=
ir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><spa=
n style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0=
,0);background-color:transparent;font-variant-numeric:normal;font-variant-e=
ast-asian:normal;vertical-align:baseline;white-space:pre-wrap">std::functio=
n<void()> b =3D mutate; =C2=A0// non-const target</span></p><p dir=3D=
"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span styl=
e=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);ba=
ckground-color:transparent;font-variant-numeric:normal;font-variant-east-as=
ian:normal;vertical-align:baseline;white-space:pre-wrap">a =3D b; =C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0// target copied</span></p><p dir=3D"ltr" style=3D"line-height:1.2=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-famil=
y:"Courier New";color:rgb(0,0,0);background-color:transparent;fon=
t-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:base=
line;white-space:pre-wrap">a(); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// now throw=
s!</span></p><h2 dir=3D"ltr" style=3D"line-height:1.38;margin-top:18pt;marg=
in-bottom:6pt"><span style=3D"font-size:16pt;font-family:Arial;color:rgb(0,=
0,0);background-color:transparent;font-weight:400;font-variant-numeric:norm=
al;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-w=
rap">Necessity and Cost</span></h2><p dir=3D"ltr" style=3D"line-height:1.38=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-famil=
y:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap">We can all agree type erased containers should support as much as =
feasible the const correctness of its target types, but we began our argume=
nt with a specific asynchronous use case that involved deferred computation=
s, often invoked on foreign threads. If this pattern as seen =E2=80=9Cin th=
e wild=E2=80=9D makes use of thread safe queues, is thread safety of the co=
ntainer itself actually sufficient to justify the costs associated with ext=
ra synchronization or exception safety? Even if we can guarantee const cont=
ainer only calls const target methods, we still cannot guarantee the target=
itself makes the connection between const and thread safety.</span></p><br=
><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"=
><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgroun=
d-color:transparent;font-variant-numeric:normal;font-variant-east-asian:nor=
mal;vertical-align:baseline;white-space:pre-wrap">Should a proposed std::un=
ique_function emulate =E2=80=9Cbroken=E2=80=9D shallow const correctness of=
std::function for uniformity, or is =E2=80=9Cfixing=E2=80=9D the contradic=
tion worth breaking runtime changes? And is std::unique_/function more like=
a container or pointer (where const is understood to be shallow), or is it=
more like an opaque type (where const is generally considered to be deep)?=
Historically we allow container const to vary independently of parameteriz=
ed types when they exist, suggesting std::function should remain a shallow =
container.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-to=
p:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;co=
lor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fon=
t-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">W=
hile this question is relevant to the specification of std::unique_function=
, it is ultimately </span><span style=3D"font-size:11pt;font-family:Arial;c=
olor:rgb(0,0,0);background-color:transparent;font-style:italic;font-variant=
-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whit=
e-space:pre-wrap">orthogonal</span><span style=3D"font-size:11pt;font-famil=
y:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap"> to the question of the need for std::unique_function to exist, wh=
ich is this paper=E2=80=99s main concern.</span></p><h1 dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:20pt;margin-bottom:6pt"><span style=3D"font=
-size:20pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;=
font-weight:400;font-variant-numeric:normal;font-variant-east-asian:normal;=
vertical-align:baseline;white-space:pre-wrap">Conclusion</span></h1><p dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span =
style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color=
:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap">So long as we have move-only lam=
bdas and type erased callable containers, a move-only capable std::function=
is required. As uniqueness semantics of container are orthogonal to const-=
correctness of the interface we recommend not conflating the two, and pursu=
ing </span><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/20=
17/p0045r1.pdf" style=3D"text-decoration-line:none"><span style=3D"font-siz=
e:11pt;font-family:Arial;background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;text-decoration-line:underline;vertic=
al-align:baseline;white-space:pre-wrap">P0045R1</span></a><span style=3D"fo=
nt-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap"> for const-correctness as an independent fe=
ature request.</span></p><h1 dir=3D"ltr" style=3D"line-height:1.38;margin-t=
op:20pt;margin-bottom:6pt"><span style=3D"font-size:20pt;font-family:Arial;=
color:rgb(0,0,0);background-color:transparent;font-weight:400;font-variant-=
numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white=
-space:pre-wrap">References</span></h1><p dir=3D"ltr" style=3D"line-height:=
1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-f=
amily:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-nume=
ric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spa=
ce:pre-wrap">[1] </span><a href=3D"https://reviews.llvm.org/D48349" style=
=3D"text-decoration-line:none"><span style=3D"font-size:11pt;font-family:Ar=
ial;background-color:transparent;font-variant-numeric:normal;font-variant-e=
ast-asian:normal;text-decoration-line:underline;vertical-align:baseline;whi=
te-space:pre-wrap">https://reviews.llvm.org/D48349</span></a></p><p dir=3D"=
ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span styl=
e=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tra=
nsparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertica=
l-align:baseline;white-space:pre-wrap">[2] </span><a href=3D"http://llvm.or=
g/doxygen/FunctionExtras_8h_source.html#l00046" style=3D"text-decoration-li=
ne:none"><span style=3D"font-size:11pt;font-family:Arial;background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;text-=
decoration-line:underline;vertical-align:baseline;white-space:pre-wrap">htt=
p://llvm.org/doxygen/FunctionExtras_8h_source.html#l00046</span></a><span s=
tyle=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:=
transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vert=
ical-align:baseline;white-space:pre-wrap"> </span></p><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">[3] </span><a href=3D"https://github.com/STEll=
AR-GROUP/hpx/blob/master/hpx/util/unique_function.hpp" style=3D"text-decora=
tion-line:none"><span style=3D"font-size:11pt;font-family:Arial;background-=
color:transparent;font-variant-numeric:normal;font-variant-east-asian:norma=
l;text-decoration-line:underline;vertical-align:baseline;white-space:pre-wr=
ap">https://github.com/STEllAR-GROUP/hpx/blob/master/hpx/util/unique_functi=
on.hpp</span></a></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0p=
t;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:=
rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">[4] <=
/span><a href=3D"https://github.com/potswa/cxx_function/blob/master/cxx_fun=
ction.hpp#L1192" style=3D"text-decoration-line:none"><span style=3D"font-si=
ze:11pt;font-family:Arial;background-color:transparent;font-variant-numeric=
:normal;font-variant-east-asian:normal;text-decoration-line:underline;verti=
cal-align:baseline;white-space:pre-wrap">https://github.com/potswa/cxx_func=
tion/blob/master/cxx_function.hpp#L1192</span></a><span style=3D"font-size:=
11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap"> </span></p><p dir=3D"ltr" style=3D"line-height:1.3=
8;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-fami=
ly:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric=
:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:=
pre-wrap">[5] </span><a href=3D"https://github.com/Naios/function2/blob/mas=
ter/include/function2/function2.hpp#L1406" style=3D"text-decoration-line:no=
ne"><span style=3D"font-size:11pt;font-family:Arial;background-color:transp=
arent;font-variant-numeric:normal;font-variant-east-asian:normal;text-decor=
ation-line:underline;vertical-align:baseline;white-space:pre-wrap">https://=
github.com/Naios/function2/blob/master/include/function2/function2.hpp#L140=
6</span></a><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0=
);background-color:transparent;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;vertical-align:baseline;white-space:pre-wrap"> </span></p><p=
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">[6] </span><a href=3D"https:=
//github.com/facebook/folly/blob/master/folly/Function.h" style=3D"text-dec=
oration-line:none"><span style=3D"font-size:11pt;font-family:Arial;backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;text-decoration-line:underline;vertical-align:baseline;white-space:pre=
-wrap">https://github.com/facebook/folly/blob/master/folly/Function.h</span=
></a><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backg=
round-color:transparent;font-variant-numeric:normal;font-variant-east-asian=
:normal;vertical-align:baseline;white-space:pre-wrap"> </span></p></span><b=
r class=3D"gmail-Apple-interchange-newline"></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/CAHn%2BA5NyaUQjAeudtObjn08Trz4iJ%2Bu-=
GGt2J5VnmtmZJiPVxg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHn%2BA5NyaU=
QjAeudtObjn08Trz4iJ%2Bu-GGt2J5VnmtmZJiPVxg%40mail.gmail.com</a>.<br />
--000000000000717da90578d549c9--
.
Author: Lee Howes <xrikcus@gmail.com>
Date: Tue, 23 Oct 2018 09:14:34 -0700
Raw View
--00000000000010371b0578e7ab81
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Hi Ryan,
Are you planning to attend the meeting and argue the case for
unique_function? This is something that came up again this week for us at
Facebook as well, and while we work around it with folly::Function as you
noted, having to do so is not optimal. It would certainly be a good thing
to get a unique_function into the standard soonish.
Lee Howes
On Mon, 22 Oct 2018 at 11:19, Ryan McDougall <mcdougall.ryan@gmail.com>
wrote:
> =E2=80=9CThis is motivated by increasing usage of things like executors a=
nd the
> task
>
> queue where it is useful to embed move-only types like a std::promise
> within
>
> a type erased function. That isn't possible without this version of a typ=
e
>
> erased function.=E2=80=9D -- Chandler Carruth[1]
> Thanks
>
> =E2=80=9Cstd::function and Beyond=E2=80=9C N4159
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf>,
> =E2=80=9CQualified std::function Signatures=E2=80=9D P0045R1
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf>,
> and =E2=80=9CA polymorphic wrapper for all Callable objects (rev. 3)=E2=
=80=9D P0288R1
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0288r1.pdf> et
> al. for laying the groundwork for this paper. Thank you to David Krauss a=
nd
> Arthur O=E2=80=99Dwyer for your discussion and feedback. Thank you all au=
thors of
> alternative type erased callable containers for your proof and inspiratio=
n.
> Motivation
>
> std::function models both CopyConstructible and CopyAssignable, and
> requires its erased target type to declare a copy constructor. This means
> std::function is hopelessly incompatible with std::unique_ptr,
> std::promise, or any other move-only type. This is a functional gap felt =
by
> C++ users to the degree that there=E2=80=99s some half-dozen popular and
> high-quality implementations available under the name =E2=80=9Cunique_fun=
ction=E2=80=9D.
> [2][3][4][5][6]
>
> C++ has many move-only vocabulary types, and when introduced they impose
> tighter constraints on the interface, and can become =E2=80=9Cviral=E2=80=
=9D -- causing any
> previously copyable paths to require move or forwarding operations. Consi=
der
>
> class DbResult {
>
> private:
>
> std::unique_ptr<Blob> data_; // now required!
>
> };
>
> class Reactor {
>
> private:
>
> std::map<std::string, std::function<void()>> reactions_;
>
> };
>
> reactor.on_event(=E2=80=9Cdb-result-ready=E2=80=9D, [&] {
>
> reactor.on_event(=E2=80=9Chas-towel=E2=80=9D, [result =3D std::move(db.r=
esult())] {
>
> auto meaning =3D find(result); // 42
>
> });
>
> });
>
> It is not enough to simply std::move the DbResult into the lambda, as
> Reactor::on_event is unable to assign to a move-only lambda as implemente=
d
> with std::function.
>
> This is a recurring pattern in much concurrent code, such as work queues,
> task graphs, or command buffers. The committee implicitly understood the
> need when it created std::packaged_task, also a type-erased polymorphic
> container, but that type is tightly bound to std::futures, which may not =
be
> fit for purpose in any code base that doesn=E2=80=99t already rely on the=
m.
>
> If we are developing any kind of asynchronous work queue we need
>
> 1.
>
> inheritance based polymorphism (and a mechanism to manage heap
> allocated derived objects, such as std::shared_ptr)
> 2.
>
> type-erased container with small object optimization like
> std::function (for copy-only callable types),
> std::packaged_task+std::future (for move-only callable types)
>
>
> However if any facet of our runtime precludes use of std::future -- such
> as if it provides its own future type, or does not use futures at all, we
> are again left without the ability to use std::unique_ptr or any other
> non-copyable type.
>
> auto unique =3D
>
> std::make_unique<BankTransfer>(=E2=80=9CDrEvil=E2=80=9D, 1000000000);
>
> auto do_bank_transfer =3D
>
> [transfer =3D std::move(unique)] (Bank* to, Bank* from) {
>
> return from->send(transfer, to);
>
> };
>
> ThreadSafeQueue<std::function<int()>> transactions1;
>
> transactions1.emplace(do_bank_transfer); // Compile Error!!
>
> // ...
>
> ThreadSafeQueue<std::packaged_task<int()>> transactions2;
>
> ThreadSafeQueue<int> results
>
> transactions2.emplace(do_bank_transfer);
>
> hpy::async([&] {
>
> while (!transactions2.empty()) {
>
> transactions2.top()();
>
> results.push_back(transactions2.top().get_future()); // ??
>
> }
>
> });
>
> In the above example we simply present wasted human time and computationa=
l
> time due to an unnecessary synchronization with std::future, however a mo=
re
> complex system may indeed need their own future implementation which
> std::packaged_task cannot interoperate with at all.
> Comparison Table
>
> std::promise<Foo> p;
>
> std::unique_ptr<Foo> f;
>
> std::queue<std::function<void()>> a;
>
> std::queue<std::unique_function<void()>> b;
>
> using namespace std;
>
>
> Before Proposal
>
> After Proposal
>
> 1
>
> auto s =3D make_shared<Foo>(move(f));
> a.emplace([s] { s->work(); });
>
>
> // ...
>
> auto shared =3D a.top();
>
> shared();
>
> b.emplace([u =3D move(f)] {
>
> u->work();
>
> });
>
> // ...
>
> auto unique =3D move(b.top());
>
> unique();
>
> 2
>
> a.emplace([r =3D f.get()] {
>
> r->work();
>
> });
>
> b.emplace([u =3D move(f)] {
>
> u->work();
>
> });
>
> 3
>
> atomic<Foo*> result{nullptr};
>
> a.emplace([&result] {
>
> result =3D new Foo;
>
> });
> // ...
> spin_on(result);
> result->work();
>
> auto future =3D p.get_future();
>
> b.emplace([p =3D move(p)] {
>
> p.set_value(Foo{});
>
> });
>
> // ...
>
> future.get().work();
>
> As you can see, attempts to work around the limitation of std::function
> results in unacceptable undermining of uniqueness semantics, life-time
> safety, and/or ease of use:
>
> 1.
>
> Loss of move-only semantics and extra LoC and a heap allocation per
> shared pointer.
> 2.
>
> Queue lifetime must not exceed enclosing scope lifetime (or dangling
> pointer).
> 3.
>
> Poor usability or unnecessary complexity in search of better
> performance.
>
> Alternatives
>
> Papers =E2=80=9Cstd::function and Beyond=E2=80=9C N4159
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf>, =E2=
=80=9CA
> polymorphic wrapper for all Callable objects (rev. 3)=E2=80=9D P0288R1
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0288r1.pdf>
> have already argued for fixing std::function to support non-copyable type=
s
> (among other issues) some time ago. Yet it seems self evident that as lon=
g
> and as widely as std::function has been in use, any change that breaks th=
e
> observable surface area of std::function is a non-starter. The question i=
s
> would the use case we outlined herein, if overlaid onto the existing
> std::function, cause previously valid code to break, or conversely
> previously incorrect code to become easily written?
>
> Let=E2=80=99s assume we have a means of =E2=80=9Cfixing=E2=80=9D std::fun=
ction to allow mixing of
> copy and move semantics. Clearly all existing code would continue to
> function as all existing target callable types are CopyConstructible and
> CopyAssignable, but what if we mix erased instances with copy and move
> semantics? How should the following operations on std::function be define=
d
> in terms of their target callable types?
>
> Let=E2=80=99s temporarily ignore the details of memory management, and co=
nsider p
> to be the underlying pointer to the erased instance.
>
> std2::function<void()> c =3D C{}; // Copy-only
> std2::function<void()> m =3D M{}; // Move-only
>
>
> Operation
>
> Definition
>
> Result
>
> c =3D std::move(m);
>
> *((M*)c.p) =3D move(*((M*)m.p));
>
> Move
>
> m =3D std::move(c);
>
> *((C*)c.p) =3D move(*((C*)m.p));
>
> Copy
>
> c =3D m;
>
> *((M*)c.p) =3D *((M*)m.p);
>
> Throw ???
>
> m =3D c;
>
> *((C*)c.p) =3D *((C*)m.p);
>
> Copy
>
> Again we face an unacceptable undermining of uniqueness semantics; in
> addition we have changed the observable surface area of assignment by
> necessitating a new runtime error reporting mechanism for when erased
> targets conflicting behavior, affecting the exception-safety of existing
> code.
> Shallow v. Deep Const
>
> =E2=80=9CShallow=E2=80=9D or =E2=80=9CDeep=E2=80=9D const in a type erase=
d context means whether the
> constness of the erasing type is extended towards the erased type. For ou=
r
> discussion we consider whether the the erasing container is const callabl=
e
> if and only if the underlying type is const callable.
>
>
> It is by now understood that the standard requires const correctness to
> imply thread-safety, and if the container operator() is const, the
> underlying callable type=E2=80=99s operator() must also be const in order=
to hope
> of satisfying this obligation. So a shallow const container could not adm=
it
> a thread-safe call operation in general, and both N4159
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf> and
> P0045R1
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf>
> draw attention to the unfortunate outcome. The solution presented in thos=
e
> papers it to include the constness of the callable in signature, and to
> have the constness of container operator() be conditional on the signatur=
e.
>
> struct Accessor {
>
> void operator()() const;
>
> // ...
>
> } access;
>
> struct Mutator {
>
> void operator()();
>
> // ...
>
> } mutate;
>
> std3::function<void() const> a =3D access; // ok
>
> std3::function<void()> b =3D access; // ok
>
> std3::function<void()> c =3D mutate; // ok
>
> std3::function<void() const> d =3D mutate; // compile error
>
> a =3D b; // compile error: target type more restrictive
>
> b =3D a; // ok
>
> b =3D c; // ok
>
>
> This proposal, while in the author=E2=80=99s opinion is highly recommende=
d
> improvement, it=E2=80=99s best presented in referenced papers, and for si=
mplicity=E2=80=99s
> sake isn=E2=80=99t pursued further here.
>
> Otherwise, without the above but desiring deep const semantics, we would
> wish that const containers require const callable targets. However, since
> we have erase the constness of target instance, we are left with throwing
> when deep const is violated, breaking existing exception-safe code.
>
> const std4::function<void()> a; // deep const
>
> std::function<void()> b =3D mutate; // non-const target
>
> a =3D b; // target copied
>
> a(); // now throws!
> Necessity and Cost
>
> We can all agree type erased containers should support as much as feasibl=
e
> the const correctness of its target types, but we began our argument with=
a
> specific asynchronous use case that involved deferred computations, often
> invoked on foreign threads. If this pattern as seen =E2=80=9Cin the wild=
=E2=80=9D makes use
> of thread safe queues, is thread safety of the container itself actually
> sufficient to justify the costs associated with extra synchronization or
> exception safety? Even if we can guarantee const container only calls con=
st
> target methods, we still cannot guarantee the target itself makes the
> connection between const and thread safety.
>
> Should a proposed std::unique_function emulate =E2=80=9Cbroken=E2=80=9D s=
hallow const
> correctness of std::function for uniformity, or is =E2=80=9Cfixing=E2=80=
=9D the
> contradiction worth breaking runtime changes? And is std::unique_/functio=
n
> more like a container or pointer (where const is understood to be shallow=
),
> or is it more like an opaque type (where const is generally considered to
> be deep)? Historically we allow container const to vary independently of
> parameterized types when they exist, suggesting std::function should rema=
in
> a shallow container.
>
> While this question is relevant to the specification of
> std::unique_function, it is ultimately orthogonal to the question of the
> need for std::unique_function to exist, which is this paper=E2=80=99s mai=
n concern.
> Conclusion
>
> So long as we have move-only lambdas and type erased callable containers,
> a move-only capable std::function is required. As uniqueness semantics of
> container are orthogonal to const-correctness of the interface we recomme=
nd
> not conflating the two, and pursuing P0045R1
> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf> for
> const-correctness as an independent feature request.
> References
>
> [1] https://reviews.llvm.org/D48349
>
> [2] http://llvm.org/doxygen/FunctionExtras_8h_source.html#l00046
>
> [3]
> https://github.com/STEllAR-GROUP/hpx/blob/master/hpx/util/unique_function=
..hpp
>
> [4]
> https://github.com/potswa/cxx_function/blob/master/cxx_function.hpp#L1192
>
> [5]
> https://github.com/Naios/function2/blob/master/include/function2/function=
2.hpp#L1406
>
> [6] https://github.com/facebook/folly/blob/master/folly/Function.h
>
> --
> 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/CAHn%2BA5Nya=
UQjAeudtObjn08Trz4iJ%2Bu-GGt2J5VnmtmZJiPVxg%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHn%2BA5Ny=
aUQjAeudtObjn08Trz4iJ%2Bu-GGt2J5VnmtmZJiPVxg%40mail.gmail.com?utm_medium=3D=
email&utm_source=3Dfooter>
> .
>
--=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/CAJH_FNW1PVw2BeYJCWfKNKN3_67eLY_6wG1vgNJOZx9oQS%=
2Bs%3DQ%40mail.gmail.com.
--00000000000010371b0578e7ab81
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Hi Ryan,<div>Are you planning to attend the meeting and ar=
gue the case for unique_function? This is something that came up again this=
week for us at Facebook as well, and while we work around it with folly::F=
unction as you noted, having to do so is not optimal. It would certainly be=
a good thing to get a unique_function into the standard soonish.</div><div=
><br></div><div>Lee Howes</div></div><br><div class=3D"gmail_quote"><div di=
r=3D"ltr">On Mon, 22 Oct 2018 at 11:19, Ryan McDougall <<a href=3D"mailt=
o:mcdougall.ryan@gmail.com">mcdougall.ryan@gmail.com</a>> wrote:<br></di=
v><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><span id=3D"m_-3924309839=
588613576gmail-docs-internal-guid-def7cea7-7fff-bf6e-c2f3-4764896f986c"><p =
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><sp=
an style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-co=
lor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;=
vertical-align:baseline;white-space:pre-wrap">=E2=80=9CThis is motivated by=
increasing usage of things like executors and the task</span></p><p dir=3D=
"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span sty=
le=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tr=
ansparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertic=
al-align:baseline;white-space:pre-wrap">queue where it is useful to embed m=
ove-only types like a std::promise within</span></p><p dir=3D"ltr" style=3D=
"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-siz=
e:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap">a type erased function. That isn't possible w=
ithout this version of a type</span></p><p dir=3D"ltr" style=3D"line-height=
:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-=
family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap">erased function.=E2=80=9D -- Chandler Carruth[1]</span></p><h=
1 dir=3D"ltr" style=3D"line-height:1.38;margin-top:20pt;margin-bottom:6pt">=
<span style=3D"font-size:20pt;font-family:Arial;color:rgb(0,0,0);background=
-color:transparent;font-weight:400;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Thanks</sp=
an></h1><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bott=
om:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);ba=
ckground-color:transparent;font-variant-numeric:normal;font-variant-east-as=
ian:normal;vertical-align:baseline;white-space:pre-wrap">=E2=80=9Cstd::func=
tion and Beyond=E2=80=9C </span><a href=3D"http://www.open-std.org/jtc1/sc2=
2/wg21/docs/papers/2014/n4159.pdf" style=3D"text-decoration-line:none" targ=
et=3D"_blank"><span style=3D"font-size:11pt;font-family:Arial;background-co=
lor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;=
text-decoration-line:underline;vertical-align:baseline;white-space:pre-wrap=
">N4159</span></a><span style=3D"font-size:11pt;font-family:Arial;color:rgb=
(0,0,0);background-color:transparent;font-variant-numeric:normal;font-varia=
nt-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">, =E2=80=
=9CQualified std::function Signatures=E2=80=9D </span><a href=3D"http://www=
..open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf" style=3D"text-de=
coration-line:none" target=3D"_blank"><span style=3D"font-size:11pt;font-fa=
mily:Arial;background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;text-decoration-line:underline;vertical-align:basel=
ine;white-space:pre-wrap">P0045R1</span></a><span style=3D"font-size:11pt;f=
ont-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant=
-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whit=
e-space:pre-wrap">, and =E2=80=9CA polymorphic wrapper for all Callable obj=
ects (rev. 3)=E2=80=9D </span><a href=3D"http://www.open-std.org/jtc1/sc22/=
wg21/docs/papers/2017/p0288r1.pdf" style=3D"text-decoration-line:none" targ=
et=3D"_blank"><span style=3D"font-size:11pt;font-family:Arial;background-co=
lor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;=
text-decoration-line:underline;vertical-align:baseline;white-space:pre-wrap=
">P0288R1</span></a><span style=3D"font-size:11pt;font-family:Arial;color:r=
gb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-var=
iant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> et al=
.. for laying the groundwork for this paper. Thank you to David Krauss and A=
rthur O=E2=80=99Dwyer for your discussion and feedback. Thank you all autho=
rs of alternative type erased callable containers for your proof and inspir=
ation.</span></p><h1 dir=3D"ltr" style=3D"line-height:1.38;margin-top:20pt;=
margin-bottom:6pt"><span style=3D"font-size:20pt;font-family:Arial;color:rg=
b(0,0,0);background-color:transparent;font-weight:400;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap">Motivation</span></h1><p dir=3D"ltr" style=3D"line-height:1.38;mar=
gin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Ar=
ial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norm=
al;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-w=
rap">std::function models both CopyConstructible and CopyAssignable, and re=
quires its erased target type to declare a copy constructor. This means std=
::function =C2=A0is hopelessly incompatible with std::unique_ptr, std::prom=
ise, or any other move-only type. This is a functional gap felt by C++ user=
s to the degree that there=E2=80=99s some half-dozen popular and high-quali=
ty implementations available under the name =E2=80=9Cunique_function=E2=80=
=9D. [2][3][4][5][6]</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-famil=
y:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap">C++ has many move-only vocabulary types, and when introduced they =
impose tighter constraints on the interface, and can become =E2=80=9Cviral=
=E2=80=9D -- causing any previously copyable paths to require move or forwa=
rding operations. Consider</span></p><br><p dir=3D"ltr" style=3D"line-heigh=
t:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font=
-family:"Courier New";color:rgb(0,0,0);background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap">class DbResult {</span></p><p dir=3D"ltr" =
style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"=
font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgro=
und-color:transparent;font-variant-numeric:normal;font-variant-east-asian:n=
ormal;vertical-align:baseline;white-space:pre-wrap"> private:</span></p><p =
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><sp=
an style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,=
0,0);background-color:transparent;font-variant-numeric:normal;font-variant-=
east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0std:=
:unique_ptr<Blob> data_; =C2=A0// now required!</span></p><p dir=3D"l=
tr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap">};</span></p><br><p=
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">class Reac=
tor {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;mar=
gin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New=
";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pr=
e-wrap"> private:</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin=
-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"=
;Courier New";color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap"> =C2=A0std::map<std::string, std::function<void()=
>> reactions_;</span></p><p dir=3D"ltr" style=3D"line-height:1.38;mar=
gin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&q=
uot;Courier New";color:rgb(0,0,0);background-color:transparent;font-va=
riant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline=
;white-space:pre-wrap">};</span></p><br><p dir=3D"ltr" style=3D"line-height=
:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-=
family:"Courier New";color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap">reactor.on_event(=E2=80=9Cdb-result-ready=
=E2=80=9D, [&] {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;mar=
gin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&q=
uot;Courier New";color:rgb(0,0,0);background-color:transparent;font-va=
riant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline=
;white-space:pre-wrap"> =C2=A0reactor.on_event(=E2=80=9Chas-towel=E2=80=9D,=
[result =3D std::move(db.result())] {</span></p><p dir=3D"ltr" style=3D"li=
ne-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
1pt;font-family:"Courier New";color:rgb(0,0,0);background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;verti=
cal-align:baseline;white-space:pre-wrap"> =C2=A0=C2=A0=C2=A0auto meaning =
=3D find(result); // 42</span></p><p dir=3D"ltr" style=3D"line-height:1.38;=
margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family=
:"Courier New";color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap"> =C2=A0});</span></p><p dir=3D"ltr" style=3D"line=
-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11p=
t;font-family:"Courier New";color:rgb(0,0,0);background-color:tra=
nsparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertica=
l-align:baseline;white-space:pre-wrap">});</span></p><br><p dir=3D"ltr" sty=
le=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"fon=
t-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent=
;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:=
baseline;white-space:pre-wrap">It is not enough to simply std::move the DbR=
esult into the lambda, as Reactor::on_event is unable to assign to a move-o=
nly lambda as implemented with std::function.</span></p><br><p dir=3D"ltr" =
style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"=
font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transpar=
ent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-ali=
gn:baseline;white-space:pre-wrap">This is a recurring pattern in much concu=
rrent code, such as work queues, task graphs, or command buffers. The commi=
ttee implicitly understood the need when it created std::packaged_task, als=
o a type-erased polymorphic container, but that type is tightly bound to st=
d::futures, which may not be fit for purpose in any code base that doesn=E2=
=80=99t already rely on them.</span></p><br><p dir=3D"ltr" style=3D"line-he=
ight:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;f=
ont-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant=
-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whit=
e-space:pre-wrap">If we are developing</span><span style=3D"font-size:11pt;=
font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-style:=
italic;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-=
align:baseline;white-space:pre-wrap"> any</span><span style=3D"font-size:11=
pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-var=
iant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;=
white-space:pre-wrap"> kind of asynchronous work queue we need </span></p><=
ol style=3D"margin-top:0pt;margin-bottom:0pt"><li dir=3D"ltr" style=3D"list=
-style-type:upper-alpha;font-size:11pt;font-family:Arial;color:rgb(0,0,0);b=
ackground-color:transparent;font-variant-numeric:normal;font-variant-east-a=
sian:normal;vertical-align:baseline;white-space:pre-wrap"><p dir=3D"ltr" st=
yle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"fo=
nt-size:11pt;background-color:transparent;font-variant-numeric:normal;font-=
variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">inh=
eritance based polymorphism (and a mechanism to manage heap allocated deriv=
ed objects, such as std::shared_ptr)</span></p></li><li dir=3D"ltr" style=
=3D"list-style-type:upper-alpha;font-size:11pt;font-family:Arial;color:rgb(=
0,0,0);background-color:transparent;font-variant-numeric:normal;font-varian=
t-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><p dir=3D=
"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span sty=
le=3D"font-size:11pt;background-color:transparent;font-variant-numeric:norm=
al;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-w=
rap">type-erased container with </span><span style=3D"font-size:11pt;backgr=
ound-color:transparent;font-style:italic;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">smal=
l object optimization</span><span style=3D"font-size:11pt;background-color:=
transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vert=
ical-align:baseline;white-space:pre-wrap"> like std::function (for copy-onl=
y callable types), std::packaged_task+std::future (for move-only callable t=
ypes)</span></p></li></ol><br><p dir=3D"ltr" style=3D"line-height:1.38;marg=
in-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Ari=
al;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">However if any facet of our runtime precludes use of std::future -- suc=
h as if it provides its own future type, or does not use futures at all, we=
are again left without the ability to use std::unique_ptr or </span><span =
style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color=
:transparent;font-weight:700;font-style:italic;font-variant-numeric:normal;=
font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap=
">any other</span><span style=3D"font-size:11pt;font-family:Arial;color:rgb=
(0,0,0);background-color:transparent;font-variant-numeric:normal;font-varia=
nt-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> non-cop=
yable type.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-t=
op:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"C=
ourier New";color:rgb(0,0,0);background-color:transparent;font-variant=
-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whit=
e-space:pre-wrap">auto unique =3D</span></p><p dir=3D"ltr" style=3D"line-he=
ight:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;f=
ont-family:"Courier New";color:rgb(0,0,0);background-color:transp=
arent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-a=
lign:baseline;white-space:pre-wrap"> =C2=A0std::make_unique<BankTransfer=
>(=E2=80=9CDrEvil=E2=80=9D, 1000000000);</span></p><br><p dir=3D"ltr" st=
yle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"fo=
nt-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgroun=
d-color:transparent;font-variant-numeric:normal;font-variant-east-asian:nor=
mal;vertical-align:baseline;white-space:pre-wrap">auto do_bank_transfer =3D=
</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-b=
ottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New"=
;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal=
;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wra=
p"> =C2=A0[transfer =3D std::move(unique)] (Bank* to, Bank* from) {</span><=
/p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0p=
t"><span style=3D"font-size:11pt;font-family:"Courier New";color:=
rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=
=A0=C2=A0=C2=A0return from->send(transfer, to);</span></p><p dir=3D"ltr"=
style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D=
"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgr=
ound-color:transparent;font-variant-numeric:normal;font-variant-east-asian:=
normal;vertical-align:baseline;white-space:pre-wrap">};</span></p><br><p di=
r=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span=
style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,=
0);background-color:transparent;font-variant-numeric:normal;font-variant-ea=
st-asian:normal;vertical-align:baseline;white-space:pre-wrap">ThreadSafeQue=
ue<std::function<int()>> transactions1;</span></p><p dir=3D"ltr=
" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap">transactions1.empla=
ce(do_bank_transfer); =C2=A0// Compile Error!!</span></p><br><p dir=3D"ltr"=
style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D=
"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgr=
ound-color:transparent;font-variant-numeric:normal;font-variant-east-asian:=
normal;vertical-align:baseline;white-space:pre-wrap">// ...</span></p><br><=
p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><=
span style=3D"font-size:11pt;font-family:"Courier New";color:rgb(=
0,0,0);background-color:transparent;font-variant-numeric:normal;font-varian=
t-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">ThreadSaf=
eQueue<std::packaged_task<int()>> transactions2;</span></p><p d=
ir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><spa=
n style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0=
,0);background-color:transparent;font-variant-numeric:normal;font-variant-e=
ast-asian:normal;vertical-align:baseline;white-space:pre-wrap">ThreadSafeQu=
eue<int> results</span></p><p dir=3D"ltr" style=3D"line-height:1.38;m=
argin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:=
"Courier New";color:rgb(0,0,0);background-color:transparent;font-=
variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseli=
ne;white-space:pre-wrap">transactions2.emplace(do_bank_transfer);</span></p=
><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:=
0pt"><span style=3D"font-size:11pt;font-family:"Courier New";colo=
r:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-=
variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">hpy=
::async([&] {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin=
-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"=
;Courier New";color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap"> =C2=A0while (!transactions2.empty()) {</span></p><p di=
r=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span=
style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,=
0);background-color:transparent;font-variant-numeric:normal;font-variant-ea=
st-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0=C2=A0=
=C2=A0transactions2.top()();</span></p><p dir=3D"ltr" style=3D"line-height:=
1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-f=
amily:"Courier New";color:rgb(0,0,0);background-color:transparent=
;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:=
baseline;white-space:pre-wrap"> =C2=A0=C2=A0=C2=A0results.push_back(transac=
tions2.top().get_future()); // ??</span></p><p dir=3D"ltr" style=3D"line-he=
ight:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;f=
ont-family:"Courier New";color:rgb(0,0,0);background-color:transp=
arent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-a=
lign:baseline;white-space:pre-wrap"> =C2=A0}</span></p><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:"Courier New";color:rgb(0,0,0);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">});</span></p><br><p dir=3D"=
ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span styl=
e=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tra=
nsparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertica=
l-align:baseline;white-space:pre-wrap">In the above example we simply prese=
nt wasted human time and computational time due to an unnecessary synchroni=
zation with std::future, however a more complex system may indeed need thei=
r own future implementation which std::packaged_task cannot interoperate wi=
th at all.</span></p><h1 dir=3D"ltr" style=3D"line-height:1.38;margin-top:2=
0pt;margin-bottom:6pt"><span style=3D"font-size:20pt;font-family:Arial;colo=
r:rgb(0,0,0);background-color:transparent;font-weight:400;font-variant-nume=
ric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spa=
ce:pre-wrap">Comparison Table</span></h1><p dir=3D"ltr" style=3D"line-heigh=
t:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font=
-family:"Courier New";color:rgb(0,0,0);background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap">std::promise<Foo> p;</span></p><p di=
r=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span=
style=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,=
0);background-color:transparent;font-variant-numeric:normal;font-variant-ea=
st-asian:normal;vertical-align:baseline;white-space:pre-wrap">std::unique_p=
tr<Foo> f;</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-t=
op:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"C=
ourier New";color:rgb(0,0,0);background-color:transparent;font-variant=
-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whit=
e-space:pre-wrap">std::queue<std::function<void()>> a;</span></=
p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"=
><span style=3D"font-size:10pt;font-family:"Courier New";color:rg=
b(0,0,0);background-color:transparent;font-variant-numeric:normal;font-vari=
ant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">std::qu=
eue<std::unique_function<void()>> b;</span></p><p dir=3D"ltr" s=
tyle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"f=
ont-size:10pt;font-family:"Courier New";color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap">using namespace std;</sp=
an></p><br><div dir=3D"ltr" style=3D"margin-left:0pt"><table style=3D"borde=
r:none;border-collapse:collapse"><colgroup><col width=3D"17"><col width=3D"=
295"><col width=3D"289"></colgroup><tbody><tr style=3D"height:0pt"><td styl=
e=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-a=
lign:top;padding:5pt"><br></td><td style=3D"border-width:1pt;border-style:s=
olid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr"=
style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"=
font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transpar=
ent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-ali=
gn:baseline;white-space:pre-wrap">Before Proposal</span></p></td><td style=
=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-al=
ign:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt=
;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:r=
gb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-var=
iant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">After =
Proposal</span></p></td></tr><tr style=3D"height:67pt"><td style=3D"border-=
width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;pad=
ding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bot=
tom:0pt"><span style=3D"font-size:10pt;font-family:Arial;color:rgb(0,0,0);b=
ackground-color:transparent;font-variant-numeric:normal;font-variant-east-a=
sian:normal;vertical-align:baseline;white-space:pre-wrap">1</span></p></td>=
<td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);ve=
rtical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margi=
n-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:&quo=
t;Courier New";color:rgb(0,0,0);background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;w=
hite-space:pre-wrap">auto s =3D make_shared<Foo>(move(f));</span><spa=
n style=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0=
,0);background-color:transparent;font-variant-numeric:normal;font-variant-e=
ast-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class=3D=
"m_-3924309839588613576gmail-kix-line-break"></span><span style=3D"font-siz=
e:10pt;font-family:"Courier New";color:rgb(0,0,0);background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ve=
rtical-align:baseline;white-space:pre-wrap">a.emplace([s] { s->work(); }=
);</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap"><br class=3D"m_-3924309839588613576gmail-kix-line-break"></span><span s=
tyle=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0)=
;background-color:transparent;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap">// ...</span></=
p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"=
><span style=3D"font-size:10pt;font-family:"Courier New";color:rg=
b(0,0,0);background-color:transparent;font-variant-numeric:normal;font-vari=
ant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">auto sh=
ared =3D a.top();</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-=
top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"=
Courier New";color:rgb(0,0,0);background-color:transparent;font-varian=
t-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whi=
te-space:pre-wrap">shared();</span></p></td><td style=3D"border-width:1pt;b=
order-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><=
p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:10pt;font-family:"Courier New";color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">b.emplace(=
[u =3D move(f)] {</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-=
top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"=
Courier New";color:rgb(0,0,0);background-color:transparent;font-varian=
t-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whi=
te-space:pre-wrap"> =C2=A0u->work();</span></p><p dir=3D"ltr" style=3D"l=
ine-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
0pt;font-family:"Courier New";color:rgb(0,0,0);background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;verti=
cal-align:baseline;white-space:pre-wrap">});</span></p><p dir=3D"ltr" style=
=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-s=
ize:10pt;font-family:"Courier New";color:rgb(0,0,0);background-co=
lor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;=
vertical-align:baseline;white-space:pre-wrap">// ...</span></p><p dir=3D"lt=
r" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap">auto unique =3D mov=
e(b.top());</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0p=
t;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courie=
r New";color:rgb(0,0,0);background-color:transparent;font-variant-nume=
ric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spa=
ce:pre-wrap">unique();</span></p></td></tr><tr style=3D"height:0pt"><td sty=
le=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-=
align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0=
pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:Arial;color=
:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">2</s=
pan></p></td><td style=3D"border-width:1pt;border-style:solid;border-color:=
rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-hei=
ght:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;fon=
t-family:"Courier New";color:rgb(0,0,0);background-color:transpar=
ent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-ali=
gn:baseline;white-space:pre-wrap">a.emplace([r =3D f.get()] {</span></p><p =
dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><spa=
n style=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0=
,0);background-color:transparent;font-variant-numeric:normal;font-variant-e=
ast-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0r->=
;work();</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;m=
argin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier N=
ew";color:rgb(0,0,0);background-color:transparent;font-variant-numeric=
:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:=
pre-wrap">});</span></p></td><td style=3D"border-width:1pt;border-style:sol=
id;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" s=
tyle=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"fo=
nt-size:10pt;font-family:"Courier New";color:rgb(0,0,0);backgroun=
d-color:transparent;font-variant-numeric:normal;font-variant-east-asian:nor=
mal;vertical-align:baseline;white-space:pre-wrap">b.emplace([u =3D move(f)]=
{</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap"> =C2=A0u->work();</span></p><p dir=3D"ltr" style=3D"line-height:1.2;=
margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family=
:"Courier New";color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap">});</span></p></td></tr><tr style=3D"height:0pt">=
<td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);ve=
rtical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margi=
n-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:Aria=
l;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal=
;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wra=
p">3</span></p></td><td style=3D"border-width:1pt;border-style:solid;border=
-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"l=
ine-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
0pt;font-family:"Courier New";color:rgb(0,0,0);background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;verti=
cal-align:baseline;white-space:pre-wrap">atomic<Foo*> result{nullptr}=
;</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-b=
ottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New"=
;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal=
;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wra=
p">a.emplace([&result] {</span></p><p dir=3D"ltr" style=3D"line-height:=
1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-fa=
mily:"Courier New";color:rgb(0,0,0);background-color:transparent;=
font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:b=
aseline;white-space:pre-wrap"> =C2=A0result =3D new Foo;</span></p><p dir=
=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span s=
tyle=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0)=
;background-color:transparent;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap">});</span><span=
style=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,=
0);background-color:transparent;font-variant-numeric:normal;font-variant-ea=
st-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class=3D"=
m_-3924309839588613576gmail-kix-line-break"></span><span style=3D"font-size=
:10pt;font-family:"Courier New";color:rgb(0,0,0);background-color=
:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap">// ...</span><span style=3D"font=
-size:10pt;font-family:"Courier New";color:rgb(0,0,0);background-=
color:transparent;font-variant-numeric:normal;font-variant-east-asian:norma=
l;vertical-align:baseline;white-space:pre-wrap"><br class=3D"m_-39243098395=
88613576gmail-kix-line-break"></span><span style=3D"font-size:10pt;font-fam=
ily:"Courier New";color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">spin_on(result);</span><span style=3D"font-siz=
e:10pt;font-family:"Courier New";color:rgb(0,0,0);background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ve=
rtical-align:baseline;white-space:pre-wrap"><br class=3D"m_-392430983958861=
3576gmail-kix-line-break"></span><span style=3D"font-size:10pt;font-family:=
"Courier New";color:rgb(0,0,0);background-color:transparent;font-=
variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseli=
ne;white-space:pre-wrap">result->work();</span></p></td><td style=3D"bor=
der-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top=
;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin=
-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New&qu=
ot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norm=
al;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-w=
rap">auto future =3D p.get_future();</span></p><p dir=3D"ltr" style=3D"line=
-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt=
;font-family:"Courier New";color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap">b.emplace([p =3D move(p)] {</span></p=
><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt">=
<span style=3D"font-size:10pt;font-family:"Courier New";color:rgb=
(0,0,0);background-color:transparent;font-variant-numeric:normal;font-varia=
nt-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0p=
..set_value(Foo{});</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin=
-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"=
;Courier New";color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap">});</span></p><p dir=3D"ltr" style=3D"line-height:1.2;m=
argin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:=
"Courier New";color:rgb(0,0,0);background-color:transparent;font-=
variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseli=
ne;white-space:pre-wrap">// ...</span></p><p dir=3D"ltr" style=3D"line-heig=
ht:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font=
-family:"Courier New";color:rgb(0,0,0);background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap">future.get().work();</span></p></td></tr><=
/tbody></table></div><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-to=
p:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;co=
lor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fon=
t-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">A=
s you can see, attempts to work around the limitation of std::function resu=
lts in unacceptable undermining of uniqueness semantics, life-time safety, =
and/or ease of use:</span></p><ol style=3D"margin-top:0pt;margin-bottom:0pt=
"><li dir=3D"ltr" style=3D"list-style-type:decimal;font-size:11pt;font-fami=
ly:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric=
:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:=
pre-wrap"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bo=
ttom:0pt"><span style=3D"font-size:11pt;background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">Loss of move-only semantics and extra LoC and a hea=
p allocation per shared pointer.</span></p></li><li dir=3D"ltr" style=3D"li=
st-style-type:decimal;font-size:11pt;font-family:Arial;color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap"><p dir=3D"ltr" styl=
e=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font=
-size:11pt;background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Queue=
lifetime must not exceed enclosing scope lifetime (or dangling pointer).</=
span></p></li><li dir=3D"ltr" style=3D"list-style-type:decimal;font-size:11=
pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-var=
iant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;=
white-space:pre-wrap"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0=
pt;margin-bottom:0pt"><span style=3D"font-size:11pt;background-color:transp=
arent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-a=
lign:baseline;white-space:pre-wrap">Poor usability or unnecessary complexit=
y in search of better performance.</span></p></li></ol><h1 dir=3D"ltr" styl=
e=3D"line-height:1.38;margin-top:20pt;margin-bottom:6pt"><span style=3D"fon=
t-size:20pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent=
;font-weight:400;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">Alternatives</span></h1><p d=
ir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><spa=
n style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-col=
or:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;v=
ertical-align:baseline;white-space:pre-wrap">Papers =E2=80=9Cstd::function =
and Beyond=E2=80=9C </span><a href=3D"http://www.open-std.org/jtc1/sc22/wg2=
1/docs/papers/2014/n4159.pdf" style=3D"text-decoration-line:none" target=3D=
"_blank"><span style=3D"font-size:11pt;font-family:Arial;background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;text-=
decoration-line:underline;vertical-align:baseline;white-space:pre-wrap">N41=
59</span></a><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,=
0);background-color:transparent;font-variant-numeric:normal;font-variant-ea=
st-asian:normal;vertical-align:baseline;white-space:pre-wrap">, =E2=80=9CA =
polymorphic wrapper for all Callable objects (rev. 3)=E2=80=9D </span><a hr=
ef=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0288r1.pdf" =
style=3D"text-decoration-line:none" target=3D"_blank"><span style=3D"font-s=
ize:11pt;font-family:Arial;background-color:transparent;font-variant-numeri=
c:normal;font-variant-east-asian:normal;text-decoration-line:underline;vert=
ical-align:baseline;white-space:pre-wrap">P0288R1</span></a><span style=3D"=
font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transpar=
ent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-ali=
gn:baseline;white-space:pre-wrap"> have already argued for fixing std::func=
tion to support non-copyable types (among other issues) some time ago. Yet =
it seems self evident that as long and as widely as std::function has been =
in use, any change that breaks the observable surface area of std::function=
is a non-starter. The question is would the use case we outlined herein, i=
f overlaid onto the existing std::function, cause previously valid code to =
break, or conversely previously incorrect code to become easily written?</s=
pan></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0=
);background-color:transparent;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;vertical-align:baseline;white-space:pre-wrap">Let=E2=80=99s =
assume we have a means of =E2=80=9Cfixing=E2=80=9D std::function to allow m=
ixing of copy and move semantics. Clearly all existing code would continue =
to function as all existing target callable types are CopyConstructible and=
CopyAssignable, but what if we mix erased instances with copy and move sem=
antics? How should the following operations on std::function be defined in =
terms of their target callable types?</span></p><br><p dir=3D"ltr" style=3D=
"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-siz=
e:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap">Let=E2=80=99s temporarily ignore the details of m=
emory management, and consider </span><span style=3D"font-size:11pt;font-fa=
mily:"Courier New";color:rgb(0,0,0);background-color:transparent;=
font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:b=
aseline;white-space:pre-wrap">p</span><span style=3D"font-size:11pt;font-fa=
mily:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numer=
ic:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spac=
e:pre-wrap"> to be the underlying pointer to the erased instance.</span></p=
><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:=
0pt"><span style=3D"font-size:11pt;font-family:"Courier New";colo=
r:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-=
variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">std=
2::function<void()> c =3D C{}; // Copy-only</span><span style=3D"font=
-size:11pt;font-family:"Courier New";color:rgb(0,0,0);background-=
color:transparent;font-variant-numeric:normal;font-variant-east-asian:norma=
l;vertical-align:baseline;white-space:pre-wrap"><br class=3D"m_-39243098395=
88613576gmail-kix-line-break"></span><span style=3D"font-size:11pt;font-fam=
ily:"Courier New";color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">std2::function<void()> m =3D M{}; // Mov=
e-only</span></p><br><br><div dir=3D"ltr" style=3D"margin-left:0pt"><table =
style=3D"border:none;border-collapse:collapse"><colgroup><col width=3D"163"=
><col width=3D"276"><col width=3D"166"></colgroup><tbody><tr style=3D"heigh=
t:0pt"><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,=
0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.=
38;margin-top:0pt;margin-bottom:0pt;text-align:center"><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">Operation</span></p></td><td style=3D"border-w=
idth:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;padd=
ing:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bot=
tom:0pt;text-align:center"><span style=3D"font-size:11pt;font-family:Arial;=
color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;f=
ont-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"=
>Definition</span></p></td><td style=3D"border-width:1pt;border-style:solid=
;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" sty=
le=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt;text-align:center">=
<span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background=
-color:transparent;font-variant-numeric:normal;font-variant-east-asian:norm=
al;vertical-align:baseline;white-space:pre-wrap">Result</span></p></td></tr=
><tr style=3D"height:0pt"><td style=3D"border-width:1pt;border-style:solid;=
border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" styl=
e=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font=
-size:11pt;font-family:"Courier New";color:rgb(0,0,0);background-=
color:transparent;font-variant-numeric:normal;font-variant-east-asian:norma=
l;vertical-align:baseline;white-space:pre-wrap">c =3D std::move(m);</span><=
/p></td><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0=
,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1=
..38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-fa=
mily:"Courier New";color:rgb(0,0,0);background-color:transparent;=
font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:b=
aseline;white-space:pre-wrap">*((M*)c.p) =3D move(*((M*)m.p));</span></p></=
td><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0)=
;vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;m=
argin-top:0pt;margin-bottom:0pt;text-align:center"><span style=3D"font-size=
:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-=
variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseli=
ne;white-space:pre-wrap">Move</span></p></td></tr><tr style=3D"height:0pt">=
<td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);ve=
rtical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;marg=
in-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&qu=
ot;Courier New";color:rgb(0,0,0);background-color:transparent;font-var=
iant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;=
white-space:pre-wrap">m =3D std::move(c);</span></p></td><td style=3D"borde=
r-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;p=
adding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">*((C*)c.p) =3D move(*((C*)m.p));</span></p></td><td style=3D"border-wid=
th:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;paddin=
g:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-botto=
m:0pt;text-align:center"><span style=3D"font-size:11pt;font-family:Arial;co=
lor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fon=
t-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">C=
opy</span></p></td></tr><tr style=3D"height:0pt"><td style=3D"border-width:=
1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5=
pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0=
pt"><span style=3D"font-size:11pt;font-family:"Courier New";color=
:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">c =
=3D m;</span></p></td><td style=3D"border-width:1pt;border-style:solid;bord=
er-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D=
"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-siz=
e:11pt;font-family:"Courier New";color:rgb(153,153,153);backgroun=
d-color:transparent;font-variant-numeric:normal;font-variant-east-asian:nor=
mal;vertical-align:baseline;white-space:pre-wrap">*((M*)c.p) =3D *((M*)m.p)=
;</span></p></td><td style=3D"border-width:1pt;border-style:solid;border-co=
lor:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line=
-height:1.38;margin-top:0pt;margin-bottom:0pt;text-align:center"><span styl=
e=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tra=
nsparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertica=
l-align:baseline;white-space:pre-wrap">Throw ???</span></p></td></tr><tr st=
yle=3D"height:0pt"><td style=3D"border-width:1pt;border-style:solid;border-=
color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"li=
ne-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
1pt;font-family:"Courier New";color:rgb(0,0,0);background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;verti=
cal-align:baseline;white-space:pre-wrap">m =3D c;</span></p></td><td style=
=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-al=
ign:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0p=
t;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courie=
r New";color:rgb(0,0,0);background-color:transparent;font-variant-nume=
ric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spa=
ce:pre-wrap">*((C*)c.p) =3D *((C*)m.p);</span></p></td><td style=3D"border-=
width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;pad=
ding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bo=
ttom:0pt;text-align:center"><span style=3D"font-size:11pt;font-family:Arial=
;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;=
font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap=
">Copy</span></p></td></tr></tbody></table></div><br><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">Again we face an unacceptable undermining of u=
niqueness semantics; in addition we have changed the observable surface are=
a of assignment by necessitating a new runtime error reporting mechanism fo=
r when erased targets conflicting behavior, affecting the exception-safety =
of existing code.</span></p><h2 dir=3D"ltr" style=3D"line-height:1.38;margi=
n-top:18pt;margin-bottom:6pt"><span style=3D"font-size:16pt;font-family:Ari=
al;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap">Shallow v. Deep Const</span></h2><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">=E2=80=9CShallow=E2=80=9D or =E2=80=9CDeep=E2=
=80=9D const in a type erased context means whether the constness of the er=
asing type is extended towards the erased type. For our discussion we consi=
der whether the the erasing container is const callable if and only if the =
underlying type is const callable.</span></p><p dir=3D"ltr" style=3D"line-h=
eight:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;=
font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varian=
t-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whi=
te-space:pre-wrap"><br class=3D"m_-3924309839588613576gmail-kix-line-break"=
></span><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);ba=
ckground-color:transparent;font-variant-numeric:normal;font-variant-east-as=
ian:normal;vertical-align:baseline;white-space:pre-wrap">It is by now under=
stood that the standard requires const correctness to imply thread-safety, =
and if the container operator() is const, the underlying callable type=E2=
=80=99s operator() must also be const in order to </span><span style=3D"fon=
t-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent=
;font-style:italic;font-variant-numeric:normal;font-variant-east-asian:norm=
al;vertical-align:baseline;white-space:pre-wrap">hope</span><span style=3D"=
font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transpar=
ent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-ali=
gn:baseline;white-space:pre-wrap"> of satisfying this obligation. So a shal=
low const container could not admit a thread-safe call operation in general=
, and both </span><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/pa=
pers/2014/n4159.pdf" style=3D"text-decoration-line:none" target=3D"_blank">=
<span style=3D"font-size:11pt;font-family:Arial;background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;text-decoratio=
n-line:underline;vertical-align:baseline;white-space:pre-wrap">N4159</span>=
</a><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgr=
ound-color:transparent;font-variant-numeric:normal;font-variant-east-asian:=
normal;vertical-align:baseline;white-space:pre-wrap"> and </span><a href=3D=
"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf" style=
=3D"text-decoration-line:none" target=3D"_blank"><span style=3D"font-size:1=
1pt;font-family:Arial;background-color:transparent;font-variant-numeric:nor=
mal;font-variant-east-asian:normal;text-decoration-line:underline;vertical-=
align:baseline;white-space:pre-wrap">P0045R1</span></a><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap"> draw attention to the unfortunate outcome. Th=
e solution presented in those papers it to include the constness of the cal=
lable in signature, and to have the constness of container operator() be co=
nditional on the signature.</span><span style=3D"font-size:11pt;font-family=
:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pr=
e-wrap"><br class=3D"m_-3924309839588613576gmail-kix-line-break"><br class=
=3D"m_-3924309839588613576gmail-kix-line-break"></span></p><p dir=3D"ltr" s=
tyle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"f=
ont-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap">struct Accessor {</span>=
</p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0=
pt"><span style=3D"font-size:11pt;font-family:"Courier New";color=
:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=
=A0void operator()() const;</span></p><p dir=3D"ltr" style=3D"line-height:1=
..38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-fa=
mily:"Courier New";color:rgb(0,0,0);background-color:transparent;=
font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:b=
aseline;white-space:pre-wrap"> =C2=A0// ...</span></p><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:"Courier New";color:rgb(0,0,0);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">} access;</span></p><br><p d=
ir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><spa=
n style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0=
,0);background-color:transparent;font-variant-numeric:normal;font-variant-e=
ast-asian:normal;vertical-align:baseline;white-space:pre-wrap">struct Mutat=
or {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;marg=
in-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&=
quot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre=
-wrap"> =C2=A0void operator()();</span></p><p dir=3D"ltr" style=3D"line-hei=
ght:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;fo=
nt-family:"Courier New";color:rgb(0,0,0);background-color:transpa=
rent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-al=
ign:baseline;white-space:pre-wrap"> =C2=A0// ...</span></p><p dir=3D"ltr" s=
tyle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"f=
ont-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap">} mutate;</span></p><br>=
<p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt">=
<span style=3D"font-size:11pt;font-family:"Courier New";color:rgb=
(0,0,0);background-color:transparent;font-variant-numeric:normal;font-varia=
nt-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">std3::fu=
nction<void() const> a =3D access; =C2=A0// ok</span></p><p dir=3D"lt=
r" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap">std3::function<v=
oid()> b =3D access; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// ok</sp=
an></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-botto=
m:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";co=
lor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fon=
t-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">s=
td3::function<void()> c =3D mutate; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0// ok</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-to=
p:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Co=
urier New";color:rgb(0,0,0);background-color:transparent;font-variant-=
numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white=
-space:pre-wrap">std3::function<void() const> d =3D mutate; =C2=A0// =
compile error</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin=
-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"=
;Courier New";color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap">a =3D b; =C2=A0// compile error: target type more restr=
ictive</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;ma=
rgin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier Ne=
w";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap">b =3D a; =C2=A0// ok</span></p><p dir=3D"ltr" style=3D"line-height=
:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-=
family:"Courier New";color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap">b =3D c; =C2=A0// ok</span></p><p dir=3D"lt=
r" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap"><br class=3D"m_-3924309839588613576gm=
ail-kix-line-break"></span><span style=3D"font-size:11pt;font-family:Arial;=
color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;f=
ont-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"=
>This proposal, while in the author=E2=80=99s opinion is highly recommended=
improvement, it=E2=80=99s best presented in referenced papers, and for sim=
plicity=E2=80=99s sake isn=E2=80=99t pursued further here.</span></p><br><p=
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">Otherwise, without the above=
but desiring deep const semantics, we would wish that const containers req=
uire const callable targets. However, since we have erase the constness of =
target instance, we are left with throwing when deep const is violated, bre=
aking existing exception-safe code.</span></p><br><p dir=3D"ltr" style=3D"l=
ine-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:=
11pt;font-family:"Courier New";color:rgb(0,0,0);background-color:=
transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vert=
ical-align:baseline;white-space:pre-wrap">const std4::function<void()>=
; a; =C2=A0=C2=A0=C2=A0// deep const</span></p><p dir=3D"ltr" style=3D"line=
-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11p=
t;font-family:"Courier New";color:rgb(0,0,0);background-color:tra=
nsparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertica=
l-align:baseline;white-space:pre-wrap">std::function<void()> b =3D mu=
tate; =C2=A0// non-const target</span></p><p dir=3D"ltr" style=3D"line-heig=
ht:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font=
-family:"Courier New";color:rgb(0,0,0);background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap">a =3D b; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// target copie=
d</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-b=
ottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New"=
;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal=
;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wra=
p">a(); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// now throws!</span></p><h2 dir=3D"=
ltr" style=3D"line-height:1.38;margin-top:18pt;margin-bottom:6pt"><span sty=
le=3D"font-size:16pt;font-family:Arial;color:rgb(0,0,0);background-color:tr=
ansparent;font-weight:400;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap">Necessity and Cost<=
/span></h2><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-b=
ottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0)=
;background-color:transparent;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap">We can all agre=
e type erased containers should support as much as feasible the const corre=
ctness of its target types, but we began our argument with a specific async=
hronous use case that involved deferred computations, often invoked on fore=
ign threads. If this pattern as seen =E2=80=9Cin the wild=E2=80=9D makes us=
e of thread safe queues, is thread safety of the container itself actually =
sufficient to justify the costs associated with extra synchronization or ex=
ception safety? Even if we can guarantee const container only calls const t=
arget methods, we still cannot guarantee the target itself makes the connec=
tion between const and thread safety.</span></p><br><p dir=3D"ltr" style=3D=
"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-siz=
e:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap">Should a proposed std::unique_function emulate =
=E2=80=9Cbroken=E2=80=9D shallow const correctness of std::function for uni=
formity, or is =E2=80=9Cfixing=E2=80=9D the contradiction worth breaking ru=
ntime changes? And is std::unique_/function more like a container or pointe=
r (where const is understood to be shallow), or is it more like an opaque t=
ype (where const is generally considered to be deep)? Historically we allow=
container const to vary independently of parameterized types when they exi=
st, suggesting std::function should remain a shallow container.</span></p><=
br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0p=
t"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgro=
und-color:transparent;font-variant-numeric:normal;font-variant-east-asian:n=
ormal;vertical-align:baseline;white-space:pre-wrap">While this question is =
relevant to the specification of std::unique_function, it is ultimately </s=
pan><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgr=
ound-color:transparent;font-style:italic;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">orth=
ogonal</span><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,=
0);background-color:transparent;font-variant-numeric:normal;font-variant-ea=
st-asian:normal;vertical-align:baseline;white-space:pre-wrap"> to the quest=
ion of the need for std::unique_function to exist, which is this paper=E2=
=80=99s main concern.</span></p><h1 dir=3D"ltr" style=3D"line-height:1.38;m=
argin-top:20pt;margin-bottom:6pt"><span style=3D"font-size:20pt;font-family=
:Arial;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">Conclusion</span></h1><p dir=3D"ltr" style=3D"line-=
height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt=
;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap">So long as we have move-only lambdas and type erased ca=
llable containers, a move-only capable std::function is required. As unique=
ness semantics of container are orthogonal to const-correctness of the inte=
rface we recommend not conflating the two, and pursuing </span><a href=3D"h=
ttp://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf" style=
=3D"text-decoration-line:none" target=3D"_blank"><span style=3D"font-size:1=
1pt;font-family:Arial;background-color:transparent;font-variant-numeric:nor=
mal;font-variant-east-asian:normal;text-decoration-line:underline;vertical-=
align:baseline;white-space:pre-wrap">P0045R1</span></a><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap"> for const-correctness as an independent featu=
re request.</span></p><h1 dir=3D"ltr" style=3D"line-height:1.38;margin-top:=
20pt;margin-bottom:6pt"><span style=3D"font-size:20pt;font-family:Arial;col=
or:rgb(0,0,0);background-color:transparent;font-weight:400;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap">References</span></h1><p dir=3D"ltr" style=3D"line-height:1.3=
8;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-fami=
ly:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric=
:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:=
pre-wrap">[1] </span><a href=3D"https://reviews.llvm.org/D48349" style=3D"t=
ext-decoration-line:none" target=3D"_blank"><span style=3D"font-size:11pt;f=
ont-family:Arial;background-color:transparent;font-variant-numeric:normal;f=
ont-variant-east-asian:normal;text-decoration-line:underline;vertical-align=
:baseline;white-space:pre-wrap">https://reviews.llvm.org/D48349</span></a><=
/p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0p=
t"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgro=
und-color:transparent;font-variant-numeric:normal;font-variant-east-asian:n=
ormal;vertical-align:baseline;white-space:pre-wrap">[2] </span><a href=3D"h=
ttp://llvm.org/doxygen/FunctionExtras_8h_source.html#l00046" style=3D"text-=
decoration-line:none" target=3D"_blank"><span style=3D"font-size:11pt;font-=
family:Arial;background-color:transparent;font-variant-numeric:normal;font-=
variant-east-asian:normal;text-decoration-line:underline;vertical-align:bas=
eline;white-space:pre-wrap">http://llvm.org/doxygen/FunctionExtras_8h_sourc=
e.html#l00046</span></a><span style=3D"font-size:11pt;font-family:Arial;col=
or:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font=
-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> <=
/span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bo=
ttom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);=
background-color:transparent;font-variant-numeric:normal;font-variant-east-=
asian:normal;vertical-align:baseline;white-space:pre-wrap">[3] </span><a hr=
ef=3D"https://github.com/STEllAR-GROUP/hpx/blob/master/hpx/util/unique_func=
tion.hpp" style=3D"text-decoration-line:none" target=3D"_blank"><span style=
=3D"font-size:11pt;font-family:Arial;background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:unde=
rline;vertical-align:baseline;white-space:pre-wrap">https://github.com/STEl=
lAR-GROUP/hpx/blob/master/hpx/util/unique_function.hpp</span></a></p><p dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span =
style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color=
:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap">[4] </span><a href=3D"https://gi=
thub.com/potswa/cxx_function/blob/master/cxx_function.hpp#L1192" style=3D"t=
ext-decoration-line:none" target=3D"_blank"><span style=3D"font-size:11pt;f=
ont-family:Arial;background-color:transparent;font-variant-numeric:normal;f=
ont-variant-east-asian:normal;text-decoration-line:underline;vertical-align=
:baseline;white-space:pre-wrap">https://github.com/potswa/cxx_function/blob=
/master/cxx_function.hpp#L1192</span></a><span style=3D"font-size:11pt;font=
-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-nu=
meric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-s=
pace:pre-wrap"> </span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-=
top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;=
color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;f=
ont-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"=
>[5] </span><a href=3D"https://github.com/Naios/function2/blob/master/inclu=
de/function2/function2.hpp#L1406" style=3D"text-decoration-line:none" targe=
t=3D"_blank"><span style=3D"font-size:11pt;font-family:Arial;background-col=
or:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;t=
ext-decoration-line:underline;vertical-align:baseline;white-space:pre-wrap"=
>https://github.com/Naios/function2/blob/master/include/function2/function2=
..hpp#L1406</span></a><span style=3D"font-size:11pt;font-family:Arial;color:=
rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> </sp=
an></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-botto=
m:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap">[6] </span><a href=
=3D"https://github.com/facebook/folly/blob/master/folly/Function.h" style=
=3D"text-decoration-line:none" target=3D"_blank"><span style=3D"font-size:1=
1pt;font-family:Arial;background-color:transparent;font-variant-numeric:nor=
mal;font-variant-east-asian:normal;text-decoration-line:underline;vertical-=
align:baseline;white-space:pre-wrap">https://github.com/facebook/folly/blob=
/master/folly/Function.h</span></a><span style=3D"font-size:11pt;font-famil=
y:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap"> </span></p></span><br class=3D"m_-3924309839588613576gmail-Apple-=
interchange-newline"></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" target=3D"_=
blank">std-proposals+unsubscribe@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/CAHn%2BA5NyaUQjAeudtObjn08Trz4iJ%2Bu-=
GGt2J5VnmtmZJiPVxg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-p=
roposals/CAHn%2BA5NyaUQjAeudtObjn08Trz4iJ%2Bu-GGt2J5VnmtmZJiPVxg%40mail.gma=
il.com</a>.<br>
</blockquote></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/CAJH_FNW1PVw2BeYJCWfKNKN3_67eLY_6wG1v=
gNJOZx9oQS%2Bs%3DQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJH_FNW1PVw2=
BeYJCWfKNKN3_67eLY_6wG1vgNJOZx9oQS%2Bs%3DQ%40mail.gmail.com</a>.<br />
--00000000000010371b0578e7ab81--
.
Author: Ryan McDougall <mcdougall.ryan@gmail.com>
Date: Tue, 23 Oct 2018 09:17:45 -0700
Raw View
--0000000000007e6af00578e7b6b2
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Yes, I'll be at SD in order to push this paper -- thought I don't know if
there's room on anyone schedule. I have hope however since it's relatively
uncontroversial it can yet be fast tracked. I would very much like help
with wording if you're available.
Cheers,
On Tue, Oct 23, 2018 at 9:14 AM Lee Howes <xrikcus@gmail.com> wrote:
> Hi Ryan,
> Are you planning to attend the meeting and argue the case for
> unique_function? This is something that came up again this week for us at
> Facebook as well, and while we work around it with folly::Function as you
> noted, having to do so is not optimal. It would certainly be a good thing
> to get a unique_function into the standard soonish.
>
> Lee Howes
>
> On Mon, 22 Oct 2018 at 11:19, Ryan McDougall <mcdougall.ryan@gmail.com>
> wrote:
>
>> =E2=80=9CThis is motivated by increasing usage of things like executors =
and the
>> task
>>
>> queue where it is useful to embed move-only types like a std::promise
>> within
>>
>> a type erased function. That isn't possible without this version of a ty=
pe
>>
>> erased function.=E2=80=9D -- Chandler Carruth[1]
>> Thanks
>>
>> =E2=80=9Cstd::function and Beyond=E2=80=9C N4159
>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf>,
>> =E2=80=9CQualified std::function Signatures=E2=80=9D P0045R1
>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf>,
>> and =E2=80=9CA polymorphic wrapper for all Callable objects (rev. 3)=E2=
=80=9D P0288R1
>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0288r1.pdf> et
>> al. for laying the groundwork for this paper. Thank you to David Krauss =
and
>> Arthur O=E2=80=99Dwyer for your discussion and feedback. Thank you all a=
uthors of
>> alternative type erased callable containers for your proof and inspirati=
on.
>> Motivation
>>
>> std::function models both CopyConstructible and CopyAssignable, and
>> requires its erased target type to declare a copy constructor. This mean=
s
>> std::function is hopelessly incompatible with std::unique_ptr,
>> std::promise, or any other move-only type. This is a functional gap felt=
by
>> C++ users to the degree that there=E2=80=99s some half-dozen popular and
>> high-quality implementations available under the name =E2=80=9Cunique_fu=
nction=E2=80=9D.
>> [2][3][4][5][6]
>>
>> C++ has many move-only vocabulary types, and when introduced they impose
>> tighter constraints on the interface, and can become =E2=80=9Cviral=E2=
=80=9D -- causing any
>> previously copyable paths to require move or forwarding operations. Cons=
ider
>>
>> class DbResult {
>>
>> private:
>>
>> std::unique_ptr<Blob> data_; // now required!
>>
>> };
>>
>> class Reactor {
>>
>> private:
>>
>> std::map<std::string, std::function<void()>> reactions_;
>>
>> };
>>
>> reactor.on_event(=E2=80=9Cdb-result-ready=E2=80=9D, [&] {
>>
>> reactor.on_event(=E2=80=9Chas-towel=E2=80=9D, [result =3D std::move(db.=
result())] {
>>
>> auto meaning =3D find(result); // 42
>>
>> });
>>
>> });
>>
>> It is not enough to simply std::move the DbResult into the lambda, as
>> Reactor::on_event is unable to assign to a move-only lambda as implement=
ed
>> with std::function.
>>
>> This is a recurring pattern in much concurrent code, such as work queues=
,
>> task graphs, or command buffers. The committee implicitly understood the
>> need when it created std::packaged_task, also a type-erased polymorphic
>> container, but that type is tightly bound to std::futures, which may not=
be
>> fit for purpose in any code base that doesn=E2=80=99t already rely on th=
em.
>>
>> If we are developing any kind of asynchronous work queue we need
>>
>> 1.
>>
>> inheritance based polymorphism (and a mechanism to manage heap
>> allocated derived objects, such as std::shared_ptr)
>> 2.
>>
>> type-erased container with small object optimization like
>> std::function (for copy-only callable types),
>> std::packaged_task+std::future (for move-only callable types)
>>
>>
>> However if any facet of our runtime precludes use of std::future -- such
>> as if it provides its own future type, or does not use futures at all, w=
e
>> are again left without the ability to use std::unique_ptr or any other
>> non-copyable type.
>>
>> auto unique =3D
>>
>> std::make_unique<BankTransfer>(=E2=80=9CDrEvil=E2=80=9D, 1000000000);
>>
>> auto do_bank_transfer =3D
>>
>> [transfer =3D std::move(unique)] (Bank* to, Bank* from) {
>>
>> return from->send(transfer, to);
>>
>> };
>>
>> ThreadSafeQueue<std::function<int()>> transactions1;
>>
>> transactions1.emplace(do_bank_transfer); // Compile Error!!
>>
>> // ...
>>
>> ThreadSafeQueue<std::packaged_task<int()>> transactions2;
>>
>> ThreadSafeQueue<int> results
>>
>> transactions2.emplace(do_bank_transfer);
>>
>> hpy::async([&] {
>>
>> while (!transactions2.empty()) {
>>
>> transactions2.top()();
>>
>> results.push_back(transactions2.top().get_future()); // ??
>>
>> }
>>
>> });
>>
>> In the above example we simply present wasted human time and
>> computational time due to an unnecessary synchronization with std::futur=
e,
>> however a more complex system may indeed need their own future
>> implementation which std::packaged_task cannot interoperate with at all.
>> Comparison Table
>>
>> std::promise<Foo> p;
>>
>> std::unique_ptr<Foo> f;
>>
>> std::queue<std::function<void()>> a;
>>
>> std::queue<std::unique_function<void()>> b;
>>
>> using namespace std;
>>
>>
>> Before Proposal
>>
>> After Proposal
>>
>> 1
>>
>> auto s =3D make_shared<Foo>(move(f));
>> a.emplace([s] { s->work(); });
>>
>>
>> // ...
>>
>> auto shared =3D a.top();
>>
>> shared();
>>
>> b.emplace([u =3D move(f)] {
>>
>> u->work();
>>
>> });
>>
>> // ...
>>
>> auto unique =3D move(b.top());
>>
>> unique();
>>
>> 2
>>
>> a.emplace([r =3D f.get()] {
>>
>> r->work();
>>
>> });
>>
>> b.emplace([u =3D move(f)] {
>>
>> u->work();
>>
>> });
>>
>> 3
>>
>> atomic<Foo*> result{nullptr};
>>
>> a.emplace([&result] {
>>
>> result =3D new Foo;
>>
>> });
>> // ...
>> spin_on(result);
>> result->work();
>>
>> auto future =3D p.get_future();
>>
>> b.emplace([p =3D move(p)] {
>>
>> p.set_value(Foo{});
>>
>> });
>>
>> // ...
>>
>> future.get().work();
>>
>> As you can see, attempts to work around the limitation of std::function
>> results in unacceptable undermining of uniqueness semantics, life-time
>> safety, and/or ease of use:
>>
>> 1.
>>
>> Loss of move-only semantics and extra LoC and a heap allocation per
>> shared pointer.
>> 2.
>>
>> Queue lifetime must not exceed enclosing scope lifetime (or dangling
>> pointer).
>> 3.
>>
>> Poor usability or unnecessary complexity in search of better
>> performance.
>>
>> Alternatives
>>
>> Papers =E2=80=9Cstd::function and Beyond=E2=80=9C N4159
>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf>, =E2=
=80=9CA
>> polymorphic wrapper for all Callable objects (rev. 3)=E2=80=9D P0288R1
>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0288r1.pdf>
>> have already argued for fixing std::function to support non-copyable typ=
es
>> (among other issues) some time ago. Yet it seems self evident that as lo=
ng
>> and as widely as std::function has been in use, any change that breaks t=
he
>> observable surface area of std::function is a non-starter. The question =
is
>> would the use case we outlined herein, if overlaid onto the existing
>> std::function, cause previously valid code to break, or conversely
>> previously incorrect code to become easily written?
>>
>> Let=E2=80=99s assume we have a means of =E2=80=9Cfixing=E2=80=9D std::fu=
nction to allow mixing of
>> copy and move semantics. Clearly all existing code would continue to
>> function as all existing target callable types are CopyConstructible and
>> CopyAssignable, but what if we mix erased instances with copy and move
>> semantics? How should the following operations on std::function be defin=
ed
>> in terms of their target callable types?
>>
>> Let=E2=80=99s temporarily ignore the details of memory management, and c=
onsider p
>> to be the underlying pointer to the erased instance.
>>
>> std2::function<void()> c =3D C{}; // Copy-only
>> std2::function<void()> m =3D M{}; // Move-only
>>
>>
>> Operation
>>
>> Definition
>>
>> Result
>>
>> c =3D std::move(m);
>>
>> *((M*)c.p) =3D move(*((M*)m.p));
>>
>> Move
>>
>> m =3D std::move(c);
>>
>> *((C*)c.p) =3D move(*((C*)m.p));
>>
>> Copy
>>
>> c =3D m;
>>
>> *((M*)c.p) =3D *((M*)m.p);
>>
>> Throw ???
>>
>> m =3D c;
>>
>> *((C*)c.p) =3D *((C*)m.p);
>>
>> Copy
>>
>> Again we face an unacceptable undermining of uniqueness semantics; in
>> addition we have changed the observable surface area of assignment by
>> necessitating a new runtime error reporting mechanism for when erased
>> targets conflicting behavior, affecting the exception-safety of existing
>> code.
>> Shallow v. Deep Const
>>
>> =E2=80=9CShallow=E2=80=9D or =E2=80=9CDeep=E2=80=9D const in a type eras=
ed context means whether the
>> constness of the erasing type is extended towards the erased type. For o=
ur
>> discussion we consider whether the the erasing container is const callab=
le
>> if and only if the underlying type is const callable.
>>
>>
>> It is by now understood that the standard requires const correctness to
>> imply thread-safety, and if the container operator() is const, the
>> underlying callable type=E2=80=99s operator() must also be const in orde=
r to hope
>> of satisfying this obligation. So a shallow const container could not ad=
mit
>> a thread-safe call operation in general, and both N4159
>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf> and
>> P0045R1
>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf>
>> draw attention to the unfortunate outcome. The solution presented in tho=
se
>> papers it to include the constness of the callable in signature, and to
>> have the constness of container operator() be conditional on the signatu=
re.
>>
>> struct Accessor {
>>
>> void operator()() const;
>>
>> // ...
>>
>> } access;
>>
>> struct Mutator {
>>
>> void operator()();
>>
>> // ...
>>
>> } mutate;
>>
>> std3::function<void() const> a =3D access; // ok
>>
>> std3::function<void()> b =3D access; // ok
>>
>> std3::function<void()> c =3D mutate; // ok
>>
>> std3::function<void() const> d =3D mutate; // compile error
>>
>> a =3D b; // compile error: target type more restrictive
>>
>> b =3D a; // ok
>>
>> b =3D c; // ok
>>
>>
>> This proposal, while in the author=E2=80=99s opinion is highly recommend=
ed
>> improvement, it=E2=80=99s best presented in referenced papers, and for s=
implicity=E2=80=99s
>> sake isn=E2=80=99t pursued further here.
>>
>> Otherwise, without the above but desiring deep const semantics, we would
>> wish that const containers require const callable targets. However, sinc=
e
>> we have erase the constness of target instance, we are left with throwin=
g
>> when deep const is violated, breaking existing exception-safe code.
>>
>> const std4::function<void()> a; // deep const
>>
>> std::function<void()> b =3D mutate; // non-const target
>>
>> a =3D b; // target copied
>>
>> a(); // now throws!
>> Necessity and Cost
>>
>> We can all agree type erased containers should support as much as
>> feasible the const correctness of its target types, but we began our
>> argument with a specific asynchronous use case that involved deferred
>> computations, often invoked on foreign threads. If this pattern as seen =
=E2=80=9Cin
>> the wild=E2=80=9D makes use of thread safe queues, is thread safety of t=
he
>> container itself actually sufficient to justify the costs associated wit=
h
>> extra synchronization or exception safety? Even if we can guarantee cons=
t
>> container only calls const target methods, we still cannot guarantee the
>> target itself makes the connection between const and thread safety.
>>
>> Should a proposed std::unique_function emulate =E2=80=9Cbroken=E2=80=9D =
shallow const
>> correctness of std::function for uniformity, or is =E2=80=9Cfixing=E2=80=
=9D the
>> contradiction worth breaking runtime changes? And is std::unique_/functi=
on
>> more like a container or pointer (where const is understood to be shallo=
w),
>> or is it more like an opaque type (where const is generally considered t=
o
>> be deep)? Historically we allow container const to vary independently of
>> parameterized types when they exist, suggesting std::function should rem=
ain
>> a shallow container.
>>
>> While this question is relevant to the specification of
>> std::unique_function, it is ultimately orthogonal to the question of the
>> need for std::unique_function to exist, which is this paper=E2=80=99s ma=
in concern.
>> Conclusion
>>
>> So long as we have move-only lambdas and type erased callable containers=
,
>> a move-only capable std::function is required. As uniqueness semantics o=
f
>> container are orthogonal to const-correctness of the interface we recomm=
end
>> not conflating the two, and pursuing P0045R1
>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf>
>> for const-correctness as an independent feature request.
>> References
>>
>> [1] https://reviews.llvm.org/D48349
>>
>> [2] http://llvm.org/doxygen/FunctionExtras_8h_source.html#l00046
>>
>> [3]
>> https://github.com/STEllAR-GROUP/hpx/blob/master/hpx/util/unique_functio=
n.hpp
>>
>> [4]
>> https://github.com/potswa/cxx_function/blob/master/cxx_function.hpp#L119=
2
>>
>> [5]
>> https://github.com/Naios/function2/blob/master/include/function2/functio=
n2.hpp#L1406
>>
>> [6] https://github.com/facebook/folly/blob/master/folly/Function.h
>>
>> --
>> You received this message because you are subscribed to the Google Group=
s
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> 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/CAHn%2BA5Ny=
aUQjAeudtObjn08Trz4iJ%2Bu-GGt2J5VnmtmZJiPVxg%40mail.gmail.com
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHn%2BA5N=
yaUQjAeudtObjn08Trz4iJ%2Bu-GGt2J5VnmtmZJiPVxg%40mail.gmail.com?utm_medium=
=3Demail&utm_source=3Dfooter>
>> .
>>
> --
> 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/CAJH_FNW1PVw=
2BeYJCWfKNKN3_67eLY_6wG1vgNJOZx9oQS%2Bs%3DQ%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJH_FNW1PV=
w2BeYJCWfKNKN3_67eLY_6wG1vgNJOZx9oQS%2Bs%3DQ%40mail.gmail.com?utm_medium=3D=
email&utm_source=3Dfooter>
> .
>
--=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/CAHn%2BA5NHiEO1rTKfZOryWnW-NTqLGgim6epp-Bt03iU5w=
d-EEA%40mail.gmail.com.
--0000000000007e6af00578e7b6b2
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Yes, I'll be at SD in order to push this paper -- thou=
ght I don't know if there's room on anyone schedule. I have hope ho=
wever since it's relatively uncontroversial it can yet be fast tracked.=
I would very much like help with wording if you're available.<div><br>=
</div><div>Cheers,</div></div><br><div class=3D"gmail_quote"><div dir=3D"lt=
r">On Tue, Oct 23, 2018 at 9:14 AM Lee Howes <<a href=3D"mailto:xrikcus@=
gmail.com">xrikcus@gmail.com</a>> wrote:<br></div><blockquote class=3D"g=
mail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-l=
eft:1ex"><div dir=3D"ltr">Hi Ryan,<div>Are you planning to attend the meeti=
ng and argue the case for unique_function? This is something that came up a=
gain this week for us at Facebook as well, and while we work around it with=
folly::Function as you noted, having to do so is not optimal. It would cer=
tainly be a good thing to get a unique_function into the standard soonish.<=
/div><div><br></div><div>Lee Howes</div></div><br><div class=3D"gmail_quote=
"><div dir=3D"ltr">On Mon, 22 Oct 2018 at 11:19, Ryan McDougall <<a href=
=3D"mailto:mcdougall.ryan@gmail.com" target=3D"_blank">mcdougall.ryan@gmail=
..com</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"mar=
gin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr=
"><span id=3D"m_-1335907127606806884m_-3924309839588613576gmail-docs-intern=
al-guid-def7cea7-7fff-bf6e-c2f3-4764896f986c"><p dir=3D"ltr" style=3D"line-=
height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt=
;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap">=E2=80=9CThis is motivated by increasing usage of thing=
s like executors and the task</span></p><p dir=3D"ltr" style=3D"line-height=
:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-=
family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap">queue where it is useful to embed move-only types like a std:=
:promise within</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-t=
op:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;c=
olor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fo=
nt-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">=
a type erased function. That isn't possible without this version of a t=
ype</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margi=
n-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0=
,0);background-color:transparent;font-variant-numeric:normal;font-variant-e=
ast-asian:normal;vertical-align:baseline;white-space:pre-wrap">erased funct=
ion.=E2=80=9D -- Chandler Carruth[1]</span></p><h1 dir=3D"ltr" style=3D"lin=
e-height:1.38;margin-top:20pt;margin-bottom:6pt"><span style=3D"font-size:2=
0pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-we=
ight:400;font-variant-numeric:normal;font-variant-east-asian:normal;vertica=
l-align:baseline;white-space:pre-wrap">Thanks</span></h1><p dir=3D"ltr" sty=
le=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"fon=
t-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent=
;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:=
baseline;white-space:pre-wrap">=E2=80=9Cstd::function and Beyond=E2=80=9C <=
/span><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4=
159.pdf" style=3D"text-decoration-line:none" target=3D"_blank"><span style=
=3D"font-size:11pt;font-family:Arial;background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:unde=
rline;vertical-align:baseline;white-space:pre-wrap">N4159</span></a><span s=
tyle=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:=
transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vert=
ical-align:baseline;white-space:pre-wrap">, =E2=80=9CQualified std::functio=
n Signatures=E2=80=9D </span><a href=3D"http://www.open-std.org/jtc1/sc22/w=
g21/docs/papers/2017/p0045r1.pdf" style=3D"text-decoration-line:none" targe=
t=3D"_blank"><span style=3D"font-size:11pt;font-family:Arial;background-col=
or:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;t=
ext-decoration-line:underline;vertical-align:baseline;white-space:pre-wrap"=
>P0045R1</span></a><span style=3D"font-size:11pt;font-family:Arial;color:rg=
b(0,0,0);background-color:transparent;font-variant-numeric:normal;font-vari=
ant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">, and =
=E2=80=9CA polymorphic wrapper for all Callable objects (rev. 3)=E2=80=9D <=
/span><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0=
288r1.pdf" style=3D"text-decoration-line:none" target=3D"_blank"><span styl=
e=3D"font-size:11pt;font-family:Arial;background-color:transparent;font-var=
iant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:und=
erline;vertical-align:baseline;white-space:pre-wrap">P0288R1</span></a><spa=
n style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-col=
or:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;v=
ertical-align:baseline;white-space:pre-wrap"> et al. for laying the groundw=
ork for this paper. Thank you to David Krauss and Arthur O=E2=80=99Dwyer fo=
r your discussion and feedback. Thank you all authors of alternative type e=
rased callable containers for your proof and inspiration.</span></p><h1 dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:20pt;margin-bottom:6pt"><span=
style=3D"font-size:20pt;font-family:Arial;color:rgb(0,0,0);background-colo=
r:transparent;font-weight:400;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap">Motivation</spa=
n></h1><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-botto=
m:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap">std::function model=
s both CopyConstructible and CopyAssignable, and requires its erased target=
type to declare a copy constructor. This means std::function =C2=A0is hope=
lessly incompatible with std::unique_ptr, std::promise, or any other move-o=
nly type. This is a functional gap felt by C++ users to the degree that the=
re=E2=80=99s some half-dozen popular and high-quality implementations avail=
able under the name =E2=80=9Cunique_function=E2=80=9D. [2][3][4][5][6]</spa=
n></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bo=
ttom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);=
background-color:transparent;font-variant-numeric:normal;font-variant-east-=
asian:normal;vertical-align:baseline;white-space:pre-wrap">C++ has many mov=
e-only vocabulary types, and when introduced they impose tighter constraint=
s on the interface, and can become =E2=80=9Cviral=E2=80=9D -- causing any p=
reviously copyable paths to require move or forwarding operations. Consider=
</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;marg=
in-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&=
quot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre=
-wrap">class DbResult {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;=
margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family=
:"Courier New";color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap"> private:</span></p><p dir=3D"ltr" style=3D"line-=
height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt=
;font-family:"Courier New";color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap"> =C2=A0std::unique_ptr<Blob> da=
ta_; =C2=A0// now required!</span></p><p dir=3D"ltr" style=3D"line-height:1=
..38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-fa=
mily:"Courier New";color:rgb(0,0,0);background-color:transparent;=
font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:b=
aseline;white-space:pre-wrap">};</span></p><br><p dir=3D"ltr" style=3D"line=
-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11p=
t;font-family:"Courier New";color:rgb(0,0,0);background-color:tra=
nsparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertica=
l-align:baseline;white-space:pre-wrap">class Reactor {</span></p><p dir=3D"=
ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span styl=
e=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);ba=
ckground-color:transparent;font-variant-numeric:normal;font-variant-east-as=
ian:normal;vertical-align:baseline;white-space:pre-wrap"> private:</span></=
p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt=
"><span style=3D"font-size:11pt;font-family:"Courier New";color:r=
gb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-var=
iant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=
=A0std::map<std::string, std::function<void()>> reactions_;</sp=
an></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-botto=
m:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";co=
lor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fon=
t-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">}=
;</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;mar=
gin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New=
";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pr=
e-wrap">reactor.on_event(=E2=80=9Cdb-result-ready=E2=80=9D, [&] {</span=
></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:=
0pt"><span style=3D"font-size:11pt;font-family:"Courier New";colo=
r:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-=
variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =
=C2=A0reactor.on_event(=E2=80=9Chas-towel=E2=80=9D, [result =3D std::move(d=
b.result())] {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-to=
p:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Co=
urier New";color:rgb(0,0,0);background-color:transparent;font-variant-=
numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white=
-space:pre-wrap"> =C2=A0=C2=A0=C2=A0auto meaning =3D find(result); // 42</s=
pan></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bott=
om:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";c=
olor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fo=
nt-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">=
=C2=A0});</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0p=
t;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courie=
r New";color:rgb(0,0,0);background-color:transparent;font-variant-nume=
ric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spa=
ce:pre-wrap">});</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;mar=
gin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Ar=
ial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norm=
al;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-w=
rap">It is not enough to simply std::move the DbResult into the lambda, as =
Reactor::on_event is unable to assign to a move-only lambda as implemented =
with std::function.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;=
margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family=
:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pr=
e-wrap">This is a recurring pattern in much concurrent code, such as work q=
ueues, task graphs, or command buffers. The committee implicitly understood=
the need when it created std::packaged_task, also a type-erased polymorphi=
c container, but that type is tightly bound to std::futures, which may not =
be fit for purpose in any code base that doesn=E2=80=99t already rely on th=
em.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;m=
argin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb=
(0,0,0);background-color:transparent;font-variant-numeric:normal;font-varia=
nt-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">If we ar=
e developing</span><span style=3D"font-size:11pt;font-family:Arial;color:rg=
b(0,0,0);background-color:transparent;font-style:italic;font-variant-numeri=
c:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space=
:pre-wrap"> any</span><span style=3D"font-size:11pt;font-family:Arial;color=
:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> kin=
d of asynchronous work queue we need </span></p><ol style=3D"margin-top:0pt=
;margin-bottom:0pt"><li dir=3D"ltr" style=3D"list-style-type:upper-alpha;fo=
nt-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap"><p dir=3D"ltr" style=3D"line-height:1.38;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;background-co=
lor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;=
vertical-align:baseline;white-space:pre-wrap">inheritance based polymorphis=
m (and a mechanism to manage heap allocated derived objects, such as std::s=
hared_ptr)</span></p></li><li dir=3D"ltr" style=3D"list-style-type:upper-al=
pha;font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap"><p dir=3D"ltr" style=3D"line-height:1=
..38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;backgro=
und-color:transparent;font-variant-numeric:normal;font-variant-east-asian:n=
ormal;vertical-align:baseline;white-space:pre-wrap">type-erased container w=
ith </span><span style=3D"font-size:11pt;background-color:transparent;font-=
style:italic;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap">small object optimization</span>=
<span style=3D"font-size:11pt;background-color:transparent;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap"> like std::function (for copy-only callable types), std::pack=
aged_task+std::future (for move-only callable types)</span></p></li></ol><b=
r><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt=
"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap">However if any facet of =
our runtime precludes use of std::future -- such as if it provides its own =
future type, or does not use futures at all, we are again left without the =
ability to use std::unique_ptr or </span><span style=3D"font-size:11pt;font=
-family:Arial;color:rgb(0,0,0);background-color:transparent;font-weight:700=
;font-style:italic;font-variant-numeric:normal;font-variant-east-asian:norm=
al;vertical-align:baseline;white-space:pre-wrap">any other</span><span styl=
e=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tra=
nsparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertica=
l-align:baseline;white-space:pre-wrap"> non-copyable type.</span></p><br><p=
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">auto uniqu=
e =3D</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;mar=
gin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New=
";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pr=
e-wrap"> =C2=A0std::make_unique<BankTransfer>(=E2=80=9CDrEvil=E2=80=
=9D, 1000000000);</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&=
quot;Courier New";color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">auto do_bank_transfer =3D</span></p><p dir=3D"ltr" =
style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"=
font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgro=
und-color:transparent;font-variant-numeric:normal;font-variant-east-asian:n=
ormal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0[transfer =3D st=
d::move(unique)] (Bank* to, Bank* from) {</span></p><p dir=3D"ltr" style=3D=
"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-siz=
e:11pt;font-family:"Courier New";color:rgb(0,0,0);background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ve=
rtical-align:baseline;white-space:pre-wrap"> =C2=A0=C2=A0=C2=A0return from-=
>send(transfer, to);</span></p><p dir=3D"ltr" style=3D"line-height:1.38;=
margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family=
:"Courier New";color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap">};</span></p><br><p dir=3D"ltr" style=3D"line-hei=
ght:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;fo=
nt-family:"Courier New";color:rgb(0,0,0);background-color:transpa=
rent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-al=
ign:baseline;white-space:pre-wrap">ThreadSafeQueue<std::function<int(=
)>> transactions1;</span></p><p dir=3D"ltr" style=3D"line-height:1.38=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-famil=
y:"Courier New";color:rgb(0,0,0);background-color:transparent;fon=
t-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:base=
line;white-space:pre-wrap">transactions1.emplace(do_bank_transfer); =C2=A0/=
/ Compile Error!!</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&=
quot;Courier New";color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">// ...</span></p><br><p dir=3D"ltr" style=3D"line-h=
eight:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;=
font-family:"Courier New";color:rgb(0,0,0);background-color:trans=
parent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-=
align:baseline;white-space:pre-wrap">ThreadSafeQueue<std::packaged_task&=
lt;int()>> transactions2;</span></p><p dir=3D"ltr" style=3D"line-heig=
ht:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;fon=
t-family:"Courier New";color:rgb(0,0,0);background-color:transpar=
ent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-ali=
gn:baseline;white-space:pre-wrap">ThreadSafeQueue<int> results</span>=
</p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0=
pt"><span style=3D"font-size:11pt;font-family:"Courier New";color=
:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">tran=
sactions2.emplace(do_bank_transfer);</span></p><br><p dir=3D"ltr" style=3D"=
line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size=
:11pt;font-family:"Courier New";color:rgb(0,0,0);background-color=
:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap">hpy::async([&] {</span></p><=
p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><=
span style=3D"font-size:11pt;font-family:"Courier New";color:rgb(=
0,0,0);background-color:transparent;font-variant-numeric:normal;font-varian=
t-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0wh=
ile (!transactions2.empty()) {</span></p><p dir=3D"ltr" style=3D"line-heigh=
t:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font=
-family:"Courier New";color:rgb(0,0,0);background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap"> =C2=A0=C2=A0=C2=A0transactions2.top()();<=
/span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bo=
ttom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New"=
;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;=
font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap=
"> =C2=A0=C2=A0=C2=A0results.push_back(transactions2.top().get_future()); /=
/ ??</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;marg=
in-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&=
quot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre=
-wrap"> =C2=A0}</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-t=
op:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"C=
ourier New";color:rgb(0,0,0);background-color:transparent;font-variant=
-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whit=
e-space:pre-wrap">});</span></p><br><p dir=3D"ltr" style=3D"line-height:1.3=
8;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-fami=
ly:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric=
:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:=
pre-wrap">In the above example we simply present wasted human time and comp=
utational time due to an unnecessary synchronization with std::future, howe=
ver a more complex system may indeed need their own future implementation w=
hich std::packaged_task cannot interoperate with at all.</span></p><h1 dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:20pt;margin-bottom:6pt"><span=
style=3D"font-size:20pt;font-family:Arial;color:rgb(0,0,0);background-colo=
r:transparent;font-weight:400;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap">Comparison Tabl=
e</span></h1><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin=
-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New&qu=
ot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norm=
al;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-w=
rap">std::promise<Foo> p;</span></p><p dir=3D"ltr" style=3D"line-heig=
ht:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;fon=
t-family:"Courier New";color:rgb(0,0,0);background-color:transpar=
ent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-ali=
gn:baseline;white-space:pre-wrap">std::unique_ptr<Foo> f;</span></p><=
p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:10pt;font-family:"Courier New";color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">std::queue=
<std::function<void()>> a;</span></p><p dir=3D"ltr" style=3D"li=
ne-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10=
pt;font-family:"Courier New";color:rgb(0,0,0);background-color:tr=
ansparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertic=
al-align:baseline;white-space:pre-wrap">std::queue<std::unique_function&=
lt;void()>> b;</span></p><p dir=3D"ltr" style=3D"line-height:1.38;mar=
gin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:&q=
uot;Courier New";color:rgb(0,0,0);background-color:transparent;font-va=
riant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline=
;white-space:pre-wrap">using namespace std;</span></p><br><div dir=3D"ltr" =
style=3D"margin-left:0pt"><table style=3D"border:none;border-collapse:colla=
pse"><colgroup><col width=3D"17"><col width=3D"295"><col width=3D"289"></co=
lgroup><tbody><tr style=3D"height:0pt"><td style=3D"border-width:1pt;border=
-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><br></=
td><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0)=
;vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:A=
rial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:nor=
mal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-=
wrap">Before Proposal</span></p></td><td style=3D"border-width:1pt;border-s=
tyle:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=
=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span s=
tyle=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:=
transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vert=
ical-align:baseline;white-space:pre-wrap">After Proposal</span></p></td></t=
r><tr style=3D"height:67pt"><td style=3D"border-width:1pt;border-style:soli=
d;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" st=
yle=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"fon=
t-size:10pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent=
;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:=
baseline;white-space:pre-wrap">1</span></p></td><td style=3D"border-width:1=
pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5p=
t"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt=
"><span style=3D"font-size:10pt;font-family:"Courier New";color:r=
gb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-var=
iant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">auto s=
=3D make_shared<Foo>(move(f));</span><span style=3D"font-size:10pt;f=
ont-family:"Courier New";color:rgb(0,0,0);background-color:transp=
arent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-a=
lign:baseline;white-space:pre-wrap"><br class=3D"m_-1335907127606806884m_-3=
924309839588613576gmail-kix-line-break"></span><span style=3D"font-size:10p=
t;font-family:"Courier New";color:rgb(0,0,0);background-color:tra=
nsparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertica=
l-align:baseline;white-space:pre-wrap">a.emplace([s] { s->work(); });</s=
pan></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-botto=
m:0pt"><span style=3D"font-size:10pt;font-family:"Courier New";co=
lor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fon=
t-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><=
br class=3D"m_-1335907127606806884m_-3924309839588613576gmail-kix-line-brea=
k"></span><span style=3D"font-size:10pt;font-family:"Courier New"=
;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;=
font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap=
">// ...</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;m=
argin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier N=
ew";color:rgb(0,0,0);background-color:transparent;font-variant-numeric=
:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:=
pre-wrap">auto shared =3D a.top();</span></p><p dir=3D"ltr" style=3D"line-h=
eight:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;f=
ont-family:"Courier New";color:rgb(0,0,0);background-color:transp=
arent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-a=
lign:baseline;white-space:pre-wrap">shared();</span></p></td><td style=3D"b=
order-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:t=
op;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;marg=
in-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New&=
quot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre=
-wrap">b.emplace([u =3D move(f)] {</span></p><p dir=3D"ltr" style=3D"line-h=
eight:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;f=
ont-family:"Courier New";color:rgb(0,0,0);background-color:transp=
arent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-a=
lign:baseline;white-space:pre-wrap"> =C2=A0u->work();</span></p><p dir=
=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span s=
tyle=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0)=
;background-color:transparent;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap">});</span></p><=
p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:10pt;font-family:"Courier New";color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">// ...</sp=
an></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom=
:0pt"><span style=3D"font-size:10pt;font-family:"Courier New";col=
or:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font=
-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">au=
to unique =3D move(b.top());</span></p><p dir=3D"ltr" style=3D"line-height:=
1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-fa=
mily:"Courier New";color:rgb(0,0,0);background-color:transparent;=
font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:b=
aseline;white-space:pre-wrap">unique();</span></p></td></tr><tr style=3D"he=
ight:0pt"><td style=3D"border-width:1pt;border-style:solid;border-color:rgb=
(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height=
:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-f=
amily:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-nume=
ric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spa=
ce:pre-wrap">2</span></p></td><td style=3D"border-width:1pt;border-style:so=
lid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" =
style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"f=
ont-size:10pt;font-family:"Courier New";color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap">a.emplace([r =3D f.get()=
] {</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin=
-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New&qu=
ot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norm=
al;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-w=
rap"> =C2=A0r->work();</span></p><p dir=3D"ltr" style=3D"line-height:1.2=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-famil=
y:"Courier New";color:rgb(0,0,0);background-color:transparent;fon=
t-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:base=
line;white-space:pre-wrap">});</span></p></td><td style=3D"border-width:1pt=
;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"=
><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt">=
<span style=3D"font-size:10pt;font-family:"Courier New";color:rgb=
(0,0,0);background-color:transparent;font-variant-numeric:normal;font-varia=
nt-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">b.emplac=
e([u =3D move(f)] {</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margi=
n-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:&quo=
t;Courier New";color:rgb(0,0,0);background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;w=
hite-space:pre-wrap"> =C2=A0u->work();</span></p><p dir=3D"ltr" style=3D=
"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size=
:10pt;font-family:"Courier New";color:rgb(0,0,0);background-color=
:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap">});</span></p></td></tr><tr styl=
e=3D"height:0pt"><td style=3D"border-width:1pt;border-style:solid;border-co=
lor:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line=
-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt=
;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap">3</span></p></td><td style=3D"border-width:1pt;border-s=
tyle:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=
=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span s=
tyle=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0)=
;background-color:transparent;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap">atomic<Foo*&=
gt; result{nullptr};</span></p><p dir=3D"ltr" style=3D"line-height:1.2;marg=
in-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:&qu=
ot;Courier New";color:rgb(0,0,0);background-color:transparent;font-var=
iant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;=
white-space:pre-wrap">a.emplace([&result] {</span></p><p dir=3D"ltr" st=
yle=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"fon=
t-size:10pt;font-family:"Courier New";color:rgb(0,0,0);background=
-color:transparent;font-variant-numeric:normal;font-variant-east-asian:norm=
al;vertical-align:baseline;white-space:pre-wrap"> =C2=A0result =3D new Foo;=
</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bo=
ttom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New"=
;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;=
font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap=
">});</span><span style=3D"font-size:10pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap"><br class=3D"m_-1335907127606806884m_-3924309839588613576gmail-kix-line=
-break"></span><span style=3D"font-size:10pt;font-family:"Courier New&=
quot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre=
-wrap">// ...</span><span style=3D"font-size:10pt;font-family:"Courier=
New";color:rgb(0,0,0);background-color:transparent;font-variant-numer=
ic:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spac=
e:pre-wrap"><br class=3D"m_-1335907127606806884m_-3924309839588613576gmail-=
kix-line-break"></span><span style=3D"font-size:10pt;font-family:"Cour=
ier New";color:rgb(0,0,0);background-color:transparent;font-variant-nu=
meric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-s=
pace:pre-wrap">spin_on(result);</span><span style=3D"font-size:10pt;font-fa=
mily:"Courier New";color:rgb(0,0,0);background-color:transparent;=
font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:b=
aseline;white-space:pre-wrap"><br class=3D"m_-1335907127606806884m_-3924309=
839588613576gmail-kix-line-break"></span><span style=3D"font-size:10pt;font=
-family:"Courier New";color:rgb(0,0,0);background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap">result->work();</span></p></td><td styl=
e=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-a=
lign:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0p=
t;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courie=
r New";color:rgb(0,0,0);background-color:transparent;font-variant-nume=
ric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spa=
ce:pre-wrap">auto future =3D p.get_future();</span></p><p dir=3D"ltr" style=
=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-s=
ize:10pt;font-family:"Courier New";color:rgb(0,0,0);background-co=
lor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;=
vertical-align:baseline;white-space:pre-wrap">b.emplace([p =3D move(p)] {</=
span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bott=
om:0pt"><span style=3D"font-size:10pt;font-family:"Courier New";c=
olor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fo=
nt-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">=
=C2=A0p.set_value(Foo{});</span></p><p dir=3D"ltr" style=3D"line-height:1.=
2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-fami=
ly:"Courier New";color:rgb(0,0,0);background-color:transparent;fo=
nt-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:bas=
eline;white-space:pre-wrap">});</span></p><p dir=3D"ltr" style=3D"line-heig=
ht:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font=
-family:"Courier New";color:rgb(0,0,0);background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap">// ...</span></p><p dir=3D"ltr" style=3D"l=
ine-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
0pt;font-family:"Courier New";color:rgb(0,0,0);background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;verti=
cal-align:baseline;white-space:pre-wrap">future.get().work();</span></p></t=
d></tr></tbody></table></div><br><p dir=3D"ltr" style=3D"line-height:1.38;m=
argin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:=
Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre=
-wrap">As you can see, attempts to work around the limitation of std::funct=
ion results in unacceptable undermining of uniqueness semantics, life-time =
safety, and/or ease of use:</span></p><ol style=3D"margin-top:0pt;margin-bo=
ttom:0pt"><li dir=3D"ltr" style=3D"list-style-type:decimal;font-size:11pt;f=
ont-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant=
-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whit=
e-space:pre-wrap"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;m=
argin-bottom:0pt"><span style=3D"font-size:11pt;background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap">Loss of move-only semantics and extra LoC a=
nd a heap allocation per shared pointer.</span></p></li><li dir=3D"ltr" sty=
le=3D"list-style-type:decimal;font-size:11pt;font-family:Arial;color:rgb(0,=
0,0);background-color:transparent;font-variant-numeric:normal;font-variant-=
east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><p dir=3D"l=
tr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:11pt;background-color:transparent;font-variant-numeric:normal=
;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wra=
p">Queue lifetime must not exceed enclosing scope lifetime (or dangling poi=
nter).</span></p></li><li dir=3D"ltr" style=3D"list-style-type:decimal;font=
-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;=
font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:b=
aseline;white-space:pre-wrap"><p dir=3D"ltr" style=3D"line-height:1.38;marg=
in-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ve=
rtical-align:baseline;white-space:pre-wrap">Poor usability or unnecessary c=
omplexity in search of better performance.</span></p></li></ol><h1 dir=3D"l=
tr" style=3D"line-height:1.38;margin-top:20pt;margin-bottom:6pt"><span styl=
e=3D"font-size:20pt;font-family:Arial;color:rgb(0,0,0);background-color:tra=
nsparent;font-weight:400;font-variant-numeric:normal;font-variant-east-asia=
n:normal;vertical-align:baseline;white-space:pre-wrap">Alternatives</span><=
/h1><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0=
pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgr=
ound-color:transparent;font-variant-numeric:normal;font-variant-east-asian:=
normal;vertical-align:baseline;white-space:pre-wrap">Papers =E2=80=9Cstd::f=
unction and Beyond=E2=80=9C </span><a href=3D"http://www.open-std.org/jtc1/=
sc22/wg21/docs/papers/2014/n4159.pdf" style=3D"text-decoration-line:none" t=
arget=3D"_blank"><span style=3D"font-size:11pt;font-family:Arial;background=
-color:transparent;font-variant-numeric:normal;font-variant-east-asian:norm=
al;text-decoration-line:underline;vertical-align:baseline;white-space:pre-w=
rap">N4159</span></a><span style=3D"font-size:11pt;font-family:Arial;color:=
rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">, =E2=
=80=9CA polymorphic wrapper for all Callable objects (rev. 3)=E2=80=9D </sp=
an><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0288=
r1.pdf" style=3D"text-decoration-line:none" target=3D"_blank"><span style=
=3D"font-size:11pt;font-family:Arial;background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:unde=
rline;vertical-align:baseline;white-space:pre-wrap">P0288R1</span></a><span=
style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ve=
rtical-align:baseline;white-space:pre-wrap"> have already argued for fixing=
std::function to support non-copyable types (among other issues) some time=
ago. Yet it seems self evident that as long and as widely as std::function=
has been in use, any change that breaks the observable surface area of std=
::function is a non-starter. The question is would the use case we outlined=
herein, if overlaid onto the existing std::function, cause previously vali=
d code to break, or conversely previously incorrect code to become easily w=
ritten?</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0=
pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color=
:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Let=
=E2=80=99s assume we have a means of =E2=80=9Cfixing=E2=80=9D std::function=
to allow mixing of copy and move semantics. Clearly all existing code woul=
d continue to function as all existing target callable types are CopyConstr=
uctible and CopyAssignable, but what if we mix erased instances with copy a=
nd move semantics? How should the following operations on std::function be =
defined in terms of their target callable types?</span></p><br><p dir=3D"lt=
r" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap">Let=E2=80=99s temporarily ignore the =
details of memory management, and consider </span><span style=3D"font-size:=
11pt;font-family:"Courier New";color:rgb(0,0,0);background-color:=
transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vert=
ical-align:baseline;white-space:pre-wrap">p</span><span style=3D"font-size:=
11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap"> to be the underlying pointer to the erased instanc=
e.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;ma=
rgin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier Ne=
w";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap">std2::function<void()> c =3D C{}; // Copy-only</span><span s=
tyle=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0)=
;background-color:transparent;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class=3D"m_=
-1335907127606806884m_-3924309839588613576gmail-kix-line-break"></span><spa=
n style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0=
,0);background-color:transparent;font-variant-numeric:normal;font-variant-e=
ast-asian:normal;vertical-align:baseline;white-space:pre-wrap">std2::functi=
on<void()> m =3D M{}; // Move-only</span></p><br><br><div dir=3D"ltr"=
style=3D"margin-left:0pt"><table style=3D"border:none;border-collapse:coll=
apse"><colgroup><col width=3D"163"><col width=3D"276"><col width=3D"166"></=
colgroup><tbody><tr style=3D"height:0pt"><td style=3D"border-width:1pt;bord=
er-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p d=
ir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt;text-=
align:center"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0=
,0);background-color:transparent;font-variant-numeric:normal;font-variant-e=
ast-asian:normal;vertical-align:baseline;white-space:pre-wrap">Operation</s=
pan></p></td><td style=3D"border-width:1pt;border-style:solid;border-color:=
rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-hei=
ght:1.38;margin-top:0pt;margin-bottom:0pt;text-align:center"><span style=3D=
"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transpa=
rent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-al=
ign:baseline;white-space:pre-wrap">Definition</span></p></td><td style=3D"b=
order-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:t=
op;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;mar=
gin-bottom:0pt;text-align:center"><span style=3D"font-size:11pt;font-family=
:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pr=
e-wrap">Result</span></p></td></tr><tr style=3D"height:0pt"><td style=3D"bo=
rder-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:to=
p;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;marg=
in-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&=
quot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre=
-wrap">c =3D std::move(m);</span></p></td><td style=3D"border-width:1pt;bor=
der-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p =
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><sp=
an style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,=
0,0);background-color:transparent;font-variant-numeric:normal;font-variant-=
east-asian:normal;vertical-align:baseline;white-space:pre-wrap">*((M*)c.p) =
=3D move(*((M*)m.p));</span></p></td><td style=3D"border-width:1pt;border-s=
tyle:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt;text-al=
ign:center"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0=
);background-color:transparent;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;vertical-align:baseline;white-space:pre-wrap">Move</span></p=
></td></tr><tr style=3D"height:0pt"><td style=3D"border-width:1pt;border-st=
yle:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D=
"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span sty=
le=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);b=
ackground-color:transparent;font-variant-numeric:normal;font-variant-east-a=
sian:normal;vertical-align:baseline;white-space:pre-wrap">m =3D std::move(c=
);</span></p></td><td style=3D"border-width:1pt;border-style:solid;border-c=
olor:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"lin=
e-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11=
pt;font-family:"Courier New";color:rgb(0,0,0);background-color:tr=
ansparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertic=
al-align:baseline;white-space:pre-wrap">*((C*)c.p) =3D move(*((C*)m.p));</s=
pan></p></td><td style=3D"border-width:1pt;border-style:solid;border-color:=
rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-hei=
ght:1.38;margin-top:0pt;margin-bottom:0pt;text-align:center"><span style=3D=
"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transpa=
rent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-al=
ign:baseline;white-space:pre-wrap">Copy</span></p></td></tr><tr style=3D"he=
ight:0pt"><td style=3D"border-width:1pt;border-style:solid;border-color:rgb=
(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height=
:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-=
family:"Courier New";color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap">c =3D m;</span></p></td><td style=3D"border=
-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;pa=
dding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-b=
ottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New"=
;;color:rgb(153,153,153);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap">*((M*)c.p) =3D *((M*)m.p);</span></p></td><td style=3D"border-widt=
h:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding=
:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom=
:0pt;text-align:center"><span style=3D"font-size:11pt;font-family:Arial;col=
or:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font=
-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Th=
row ???</span></p></td></tr><tr style=3D"height:0pt"><td style=3D"border-wi=
dth:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;paddi=
ng:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bott=
om:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";c=
olor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fo=
nt-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">=
m =3D c;</span></p></td><td style=3D"border-width:1pt;border-style:solid;bo=
rder-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:"Courier New";color:rgb(0,0,0);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">*((C*)c.p) =3D *((C*)m.p);</=
span></p></td><td style=3D"border-width:1pt;border-style:solid;border-color=
:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-he=
ight:1.38;margin-top:0pt;margin-bottom:0pt;text-align:center"><span style=
=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap">Copy</span></p></td></tr></tbody></ta=
ble></div><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margi=
n-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0=
,0);background-color:transparent;font-variant-numeric:normal;font-variant-e=
ast-asian:normal;vertical-align:baseline;white-space:pre-wrap">Again we fac=
e an unacceptable undermining of uniqueness semantics; in addition we have =
changed the observable surface area of assignment by necessitating a new ru=
ntime error reporting mechanism for when erased targets conflicting behavio=
r, affecting the exception-safety of existing code.</span></p><h2 dir=3D"lt=
r" style=3D"line-height:1.38;margin-top:18pt;margin-bottom:6pt"><span style=
=3D"font-size:16pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-weight:400;font-variant-numeric:normal;font-variant-east-asian=
:normal;vertical-align:baseline;white-space:pre-wrap">Shallow v. Deep Const=
</span></h2><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0=
);background-color:transparent;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;vertical-align:baseline;white-space:pre-wrap">=E2=80=9CShall=
ow=E2=80=9D or =E2=80=9CDeep=E2=80=9D const in a type erased context means =
whether the constness of the erasing type is extended towards the erased ty=
pe. For our discussion we consider whether the the erasing container is con=
st callable if and only if the underlying type is const callable.</span></p=
><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"=
><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgroun=
d-color:transparent;font-variant-numeric:normal;font-variant-east-asian:nor=
mal;vertical-align:baseline;white-space:pre-wrap"><br class=3D"m_-133590712=
7606806884m_-3924309839588613576gmail-kix-line-break"></span><span style=3D=
"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transpa=
rent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-al=
ign:baseline;white-space:pre-wrap">It is by now understood that the standar=
d requires const correctness to imply thread-safety, and if the container o=
perator() is const, the underlying callable type=E2=80=99s operator() must =
also be const in order to </span><span style=3D"font-size:11pt;font-family:=
Arial;color:rgb(0,0,0);background-color:transparent;font-style:italic;font-=
variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseli=
ne;white-space:pre-wrap">hope</span><span style=3D"font-size:11pt;font-fami=
ly:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric=
:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:=
pre-wrap"> of satisfying this obligation. So a shallow const container coul=
d not admit a thread-safe call operation in general, and both </span><a hre=
f=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf" sty=
le=3D"text-decoration-line:none" target=3D"_blank"><span style=3D"font-size=
:11pt;font-family:Arial;background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;text-decoration-line:underline;vertica=
l-align:baseline;white-space:pre-wrap">N4159</span></a><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap"> and </span><a href=3D"http://www.open-std.org=
/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf" style=3D"text-decoration-line=
:none" target=3D"_blank"><span style=3D"font-size:11pt;font-family:Arial;ba=
ckground-color:transparent;font-variant-numeric:normal;font-variant-east-as=
ian:normal;text-decoration-line:underline;vertical-align:baseline;white-spa=
ce:pre-wrap">P0045R1</span></a><span style=3D"font-size:11pt;font-family:Ar=
ial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norm=
al;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-w=
rap"> draw attention to the unfortunate outcome. The solution presented in =
those papers it to include the constness of the callable in signature, and =
to have the constness of container operator() be conditional on the signatu=
re.</span><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);=
background-color:transparent;font-variant-numeric:normal;font-variant-east-=
asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class=3D"m_-=
1335907127606806884m_-3924309839588613576gmail-kix-line-break"><br class=3D=
"m_-1335907127606806884m_-3924309839588613576gmail-kix-line-break"></span><=
/p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0p=
t"><span style=3D"font-size:11pt;font-family:"Courier New";color:=
rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">struc=
t Accessor {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:=
0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Cour=
ier New";color:rgb(0,0,0);background-color:transparent;font-variant-nu=
meric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-s=
pace:pre-wrap"> =C2=A0void operator()() const;</span></p><p dir=3D"ltr" sty=
le=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"fon=
t-size:11pt;font-family:"Courier New";color:rgb(0,0,0);background=
-color:transparent;font-variant-numeric:normal;font-variant-east-asian:norm=
al;vertical-align:baseline;white-space:pre-wrap"> =C2=A0// ...</span></p><p=
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">} access;<=
/span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margi=
n-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&q=
uot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:nor=
mal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-=
wrap">struct Mutator {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;m=
argin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:=
"Courier New";color:rgb(0,0,0);background-color:transparent;font-=
variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseli=
ne;white-space:pre-wrap"> =C2=A0void operator()();</span></p><p dir=3D"ltr"=
style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D=
"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgr=
ound-color:transparent;font-variant-numeric:normal;font-variant-east-asian:=
normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0// ...</span></=
p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt=
"><span style=3D"font-size:11pt;font-family:"Courier New";color:r=
gb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-var=
iant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">} muta=
te;</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;m=
argin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier N=
ew";color:rgb(0,0,0);background-color:transparent;font-variant-numeric=
:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:=
pre-wrap">std3::function<void() const> a =3D access; =C2=A0// ok</spa=
n></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom=
:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";col=
or:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font=
-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">st=
d3::function<void()> b =3D access; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0// ok</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-to=
p:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Co=
urier New";color:rgb(0,0,0);background-color:transparent;font-variant-=
numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white=
-space:pre-wrap">std3::function<void()> c =3D mutate; =C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0// ok</span></p><p dir=3D"ltr" style=3D"line-hei=
ght:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;fo=
nt-family:"Courier New";color:rgb(0,0,0);background-color:transpa=
rent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-al=
ign:baseline;white-space:pre-wrap">std3::function<void() const> d =3D=
mutate; =C2=A0// compile error</span></p><br><p dir=3D"ltr" style=3D"line-=
height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt=
;font-family:"Courier New";color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap">a =3D b; =C2=A0// compile error: targ=
et type more restrictive</span></p><p dir=3D"ltr" style=3D"line-height:1.38=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-famil=
y:"Courier New";color:rgb(0,0,0);background-color:transparent;fon=
t-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:base=
line;white-space:pre-wrap">b =3D a; =C2=A0// ok</span></p><p dir=3D"ltr" st=
yle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"fo=
nt-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgroun=
d-color:transparent;font-variant-numeric:normal;font-variant-east-asian:nor=
mal;vertical-align:baseline;white-space:pre-wrap">b =3D c; =C2=A0// ok</spa=
n></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom=
:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);back=
ground-color:transparent;font-variant-numeric:normal;font-variant-east-asia=
n:normal;vertical-align:baseline;white-space:pre-wrap"><br class=3D"m_-1335=
907127606806884m_-3924309839588613576gmail-kix-line-break"></span><span sty=
le=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tr=
ansparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertic=
al-align:baseline;white-space:pre-wrap">This proposal, while in the author=
=E2=80=99s opinion is highly recommended improvement, it=E2=80=99s best pre=
sented in referenced papers, and for simplicity=E2=80=99s sake isn=E2=80=99=
t pursued further here.</span></p><br><p dir=3D"ltr" style=3D"line-height:1=
..38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-fa=
mily:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numer=
ic:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spac=
e:pre-wrap">Otherwise, without the above but desiring deep const semantics,=
we would wish that const containers require const callable targets. Howeve=
r, since we have erase the constness of target instance, we are left with t=
hrowing when deep const is violated, breaking existing exception-safe code.=
</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;marg=
in-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&=
quot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre=
-wrap">const std4::function<void()> a; =C2=A0=C2=A0=C2=A0// deep cons=
t</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">std::function<void()> b =3D mutate; =C2=A0// non-const target</sp=
an></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom=
:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";col=
or:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font=
-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">a =
=3D b; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0// target copied</span></p><p dir=3D"ltr" style=
=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-s=
ize:11pt;font-family:"Courier New";color:rgb(0,0,0);background-co=
lor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;=
vertical-align:baseline;white-space:pre-wrap">a(); =C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0// now throws!</span></p><h2 dir=3D"ltr" style=3D"line-height:1.38;ma=
rgin-top:18pt;margin-bottom:6pt"><span style=3D"font-size:16pt;font-family:=
Arial;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-va=
riant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline=
;white-space:pre-wrap">Necessity and Cost</span></h2><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">We can all agree type erased containers should=
support as much as feasible the const correctness of its target types, but=
we began our argument with a specific asynchronous use case that involved =
deferred computations, often invoked on foreign threads. If this pattern as=
seen =E2=80=9Cin the wild=E2=80=9D makes use of thread safe queues, is thr=
ead safety of the container itself actually sufficient to justify the costs=
associated with extra synchronization or exception safety? Even if we can =
guarantee const container only calls const target methods, we still cannot =
guarantee the target itself makes the connection between const and thread s=
afety.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0p=
t;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:=
rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Shoul=
d a proposed std::unique_function emulate =E2=80=9Cbroken=E2=80=9D shallow =
const correctness of std::function for uniformity, or is =E2=80=9Cfixing=E2=
=80=9D the contradiction worth breaking runtime changes? And is std::unique=
_/function more like a container or pointer (where const is understood to b=
e shallow), or is it more like an opaque type (where const is generally con=
sidered to be deep)? Historically we allow container const to vary independ=
ently of parameterized types when they exist, suggesting std::function shou=
ld remain a shallow container.</span></p><br><p dir=3D"ltr" style=3D"line-h=
eight:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;=
font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varian=
t-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whi=
te-space:pre-wrap">While this question is relevant to the specification of =
std::unique_function, it is ultimately </span><span style=3D"font-size:11pt=
;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-style=
:italic;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap">orthogonal</span><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap"> to the question of the need for std::unique_f=
unction to exist, which is this paper=E2=80=99s main concern.</span></p><h1=
dir=3D"ltr" style=3D"line-height:1.38;margin-top:20pt;margin-bottom:6pt"><=
span style=3D"font-size:20pt;font-family:Arial;color:rgb(0,0,0);background-=
color:transparent;font-weight:400;font-variant-numeric:normal;font-variant-=
east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Conclusion<=
/span></h1><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-b=
ottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0)=
;background-color:transparent;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap">So long as we h=
ave move-only lambdas and type erased callable containers, a move-only capa=
ble std::function is required. As uniqueness semantics of container are ort=
hogonal to const-correctness of the interface we recommend not conflating t=
he two, and pursuing </span><a href=3D"http://www.open-std.org/jtc1/sc22/wg=
21/docs/papers/2017/p0045r1.pdf" style=3D"text-decoration-line:none" target=
=3D"_blank"><span style=3D"font-size:11pt;font-family:Arial;background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;te=
xt-decoration-line:underline;vertical-align:baseline;white-space:pre-wrap">=
P0045R1</span></a><span style=3D"font-size:11pt;font-family:Arial;color:rgb=
(0,0,0);background-color:transparent;font-variant-numeric:normal;font-varia=
nt-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> for con=
st-correctness as an independent feature request.</span></p><h1 dir=3D"ltr"=
style=3D"line-height:1.38;margin-top:20pt;margin-bottom:6pt"><span style=
=3D"font-size:20pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-weight:400;font-variant-numeric:normal;font-variant-east-asian=
:normal;vertical-align:baseline;white-space:pre-wrap">References</span></h1=
><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"=
><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgroun=
d-color:transparent;font-variant-numeric:normal;font-variant-east-asian:nor=
mal;vertical-align:baseline;white-space:pre-wrap">[1] </span><a href=3D"htt=
ps://reviews.llvm.org/D48349" style=3D"text-decoration-line:none" target=3D=
"_blank"><span style=3D"font-size:11pt;font-family:Arial;background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;text-=
decoration-line:underline;vertical-align:baseline;white-space:pre-wrap">htt=
ps://reviews.llvm.org/D48349</span></a></p><p dir=3D"ltr" style=3D"line-hei=
ght:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;fo=
nt-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-=
numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white=
-space:pre-wrap">[2] </span><a href=3D"http://llvm.org/doxygen/FunctionExtr=
as_8h_source.html#l00046" style=3D"text-decoration-line:none" target=3D"_bl=
ank"><span style=3D"font-size:11pt;font-family:Arial;background-color:trans=
parent;font-variant-numeric:normal;font-variant-east-asian:normal;text-deco=
ration-line:underline;vertical-align:baseline;white-space:pre-wrap">http://=
llvm.org/doxygen/FunctionExtras_8h_source.html#l00046</span></a><span style=
=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap"> </span></p><p dir=3D"ltr" style=3D"l=
ine-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:=
11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">[3] </span><a href=3D"https://github.com/STEllAR-GR=
OUP/hpx/blob/master/hpx/util/unique_function.hpp" style=3D"text-decoration-=
line:none" target=3D"_blank"><span style=3D"font-size:11pt;font-family:Aria=
l;background-color:transparent;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;text-decoration-line:underline;vertical-align:baseline;white=
-space:pre-wrap">https://github.com/STEllAR-GROUP/hpx/blob/master/hpx/util/=
unique_function.hpp</span></a></p><p dir=3D"ltr" style=3D"line-height:1.38;=
margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family=
:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pr=
e-wrap">[4] </span><a href=3D"https://github.com/potswa/cxx_function/blob/m=
aster/cxx_function.hpp#L1192" style=3D"text-decoration-line:none" target=3D=
"_blank"><span style=3D"font-size:11pt;font-family:Arial;background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;text-=
decoration-line:underline;vertical-align:baseline;white-space:pre-wrap">htt=
ps://github.com/potswa/cxx_function/blob/master/cxx_function.hpp#L1192</spa=
n></a><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);back=
ground-color:transparent;font-variant-numeric:normal;font-variant-east-asia=
n:normal;vertical-align:baseline;white-space:pre-wrap"> </span></p><p dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span =
style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color=
:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap">[5] </span><a href=3D"https://gi=
thub.com/Naios/function2/blob/master/include/function2/function2.hpp#L1406"=
style=3D"text-decoration-line:none" target=3D"_blank"><span style=3D"font-=
size:11pt;font-family:Arial;background-color:transparent;font-variant-numer=
ic:normal;font-variant-east-asian:normal;text-decoration-line:underline;ver=
tical-align:baseline;white-space:pre-wrap">https://github.com/Naios/functio=
n2/blob/master/include/function2/function2.hpp#L1406</span></a><span style=
=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap"> </span></p><p dir=3D"ltr" style=3D"l=
ine-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:=
11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">[6] </span><a href=3D"https://github.com/facebook/f=
olly/blob/master/folly/Function.h" style=3D"text-decoration-line:none" targ=
et=3D"_blank"><span style=3D"font-size:11pt;font-family:Arial;background-co=
lor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;=
text-decoration-line:underline;vertical-align:baseline;white-space:pre-wrap=
">https://github.com/facebook/folly/blob/master/folly/Function.h</span></a>=
<span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background=
-color:transparent;font-variant-numeric:normal;font-variant-east-asian:norm=
al;vertical-align:baseline;white-space:pre-wrap"> </span></p></span><br cla=
ss=3D"m_-1335907127606806884m_-3924309839588613576gmail-Apple-interchange-n=
ewline"></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" target=3D"_=
blank">std-proposals+unsubscribe@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/CAHn%2BA5NyaUQjAeudtObjn08Trz4iJ%2Bu-=
GGt2J5VnmtmZJiPVxg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-p=
roposals/CAHn%2BA5NyaUQjAeudtObjn08Trz4iJ%2Bu-GGt2J5VnmtmZJiPVxg%40mail.gma=
il.com</a>.<br>
</blockquote></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" target=3D"_=
blank">std-proposals+unsubscribe@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/CAJH_FNW1PVw2BeYJCWfKNKN3_67eLY_6wG1v=
gNJOZx9oQS%2Bs%3DQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-p=
roposals/CAJH_FNW1PVw2BeYJCWfKNKN3_67eLY_6wG1vgNJOZx9oQS%2Bs%3DQ%40mail.gma=
il.com</a>.<br>
</blockquote></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/CAHn%2BA5NHiEO1rTKfZOryWnW-NTqLGgim6e=
pp-Bt03iU5wd-EEA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHn%2BA5NHiEO1=
rTKfZOryWnW-NTqLGgim6epp-Bt03iU5wd-EEA%40mail.gmail.com</a>.<br />
--0000000000007e6af00578e7b6b2--
.
Author: Lee Howes <xrikcus@gmail.com>
Date: Tue, 23 Oct 2018 09:26:05 -0700
Raw View
--0000000000004538e50578e7d491
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
From the minutes from the presentation of P0288 in Toronto it looks like
there was a request for updated wording to make it independent of P0045,
but otherwise little obvious concern. It seems likely that that's the
important change to make.
Given the paper reading load between now and SD we're going to be
overwhelmed, I think. I'd be happy to give some feedback on a wording draft
in the short term.
On Tue, 23 Oct 2018 at 09:18, Ryan McDougall <mcdougall.ryan@gmail.com>
wrote:
> Yes, I'll be at SD in order to push this paper -- thought I don't know if
> there's room on anyone schedule. I have hope however since it's relativel=
y
> uncontroversial it can yet be fast tracked. I would very much like help
> with wording if you're available.
>
> Cheers,
>
> On Tue, Oct 23, 2018 at 9:14 AM Lee Howes <xrikcus@gmail.com> wrote:
>
>> Hi Ryan,
>> Are you planning to attend the meeting and argue the case for
>> unique_function? This is something that came up again this week for us a=
t
>> Facebook as well, and while we work around it with folly::Function as yo=
u
>> noted, having to do so is not optimal. It would certainly be a good thin=
g
>> to get a unique_function into the standard soonish.
>>
>> Lee Howes
>>
>> On Mon, 22 Oct 2018 at 11:19, Ryan McDougall <mcdougall.ryan@gmail.com>
>> wrote:
>>
>>> =E2=80=9CThis is motivated by increasing usage of things like executors=
and the
>>> task
>>>
>>> queue where it is useful to embed move-only types like a std::promise
>>> within
>>>
>>> a type erased function. That isn't possible without this version of a
>>> type
>>>
>>> erased function.=E2=80=9D -- Chandler Carruth[1]
>>> Thanks
>>>
>>> =E2=80=9Cstd::function and Beyond=E2=80=9C N4159
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf>,
>>> =E2=80=9CQualified std::function Signatures=E2=80=9D P0045R1
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf>,
>>> and =E2=80=9CA polymorphic wrapper for all Callable objects (rev. 3)=E2=
=80=9D P0288R1
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0288r1.pdf>
>>> et al. for laying the groundwork for this paper. Thank you to David Kra=
uss
>>> and Arthur O=E2=80=99Dwyer for your discussion and feedback. Thank you =
all authors
>>> of alternative type erased callable containers for your proof and
>>> inspiration.
>>> Motivation
>>>
>>> std::function models both CopyConstructible and CopyAssignable, and
>>> requires its erased target type to declare a copy constructor. This mea=
ns
>>> std::function is hopelessly incompatible with std::unique_ptr,
>>> std::promise, or any other move-only type. This is a functional gap fel=
t by
>>> C++ users to the degree that there=E2=80=99s some half-dozen popular an=
d
>>> high-quality implementations available under the name =E2=80=9Cunique_f=
unction=E2=80=9D.
>>> [2][3][4][5][6]
>>>
>>> C++ has many move-only vocabulary types, and when introduced they impos=
e
>>> tighter constraints on the interface, and can become =E2=80=9Cviral=E2=
=80=9D -- causing any
>>> previously copyable paths to require move or forwarding operations. Con=
sider
>>>
>>> class DbResult {
>>>
>>> private:
>>>
>>> std::unique_ptr<Blob> data_; // now required!
>>>
>>> };
>>>
>>> class Reactor {
>>>
>>> private:
>>>
>>> std::map<std::string, std::function<void()>> reactions_;
>>>
>>> };
>>>
>>> reactor.on_event(=E2=80=9Cdb-result-ready=E2=80=9D, [&] {
>>>
>>> reactor.on_event(=E2=80=9Chas-towel=E2=80=9D, [result =3D std::move(db=
..result())] {
>>>
>>> auto meaning =3D find(result); // 42
>>>
>>> });
>>>
>>> });
>>>
>>> It is not enough to simply std::move the DbResult into the lambda, as
>>> Reactor::on_event is unable to assign to a move-only lambda as implemen=
ted
>>> with std::function.
>>>
>>> This is a recurring pattern in much concurrent code, such as work
>>> queues, task graphs, or command buffers. The committee implicitly
>>> understood the need when it created std::packaged_task, also a type-era=
sed
>>> polymorphic container, but that type is tightly bound to std::futures,
>>> which may not be fit for purpose in any code base that doesn=E2=80=99t =
already rely
>>> on them.
>>>
>>> If we are developing any kind of asynchronous work queue we need
>>>
>>> 1.
>>>
>>> inheritance based polymorphism (and a mechanism to manage heap
>>> allocated derived objects, such as std::shared_ptr)
>>> 2.
>>>
>>> type-erased container with small object optimization like
>>> std::function (for copy-only callable types),
>>> std::packaged_task+std::future (for move-only callable types)
>>>
>>>
>>> However if any facet of our runtime precludes use of std::future -- suc=
h
>>> as if it provides its own future type, or does not use futures at all, =
we
>>> are again left without the ability to use std::unique_ptr or any other
>>> non-copyable type.
>>>
>>> auto unique =3D
>>>
>>> std::make_unique<BankTransfer>(=E2=80=9CDrEvil=E2=80=9D, 1000000000);
>>>
>>> auto do_bank_transfer =3D
>>>
>>> [transfer =3D std::move(unique)] (Bank* to, Bank* from) {
>>>
>>> return from->send(transfer, to);
>>>
>>> };
>>>
>>> ThreadSafeQueue<std::function<int()>> transactions1;
>>>
>>> transactions1.emplace(do_bank_transfer); // Compile Error!!
>>>
>>> // ...
>>>
>>> ThreadSafeQueue<std::packaged_task<int()>> transactions2;
>>>
>>> ThreadSafeQueue<int> results
>>>
>>> transactions2.emplace(do_bank_transfer);
>>>
>>> hpy::async([&] {
>>>
>>> while (!transactions2.empty()) {
>>>
>>> transactions2.top()();
>>>
>>> results.push_back(transactions2.top().get_future()); // ??
>>>
>>> }
>>>
>>> });
>>>
>>> In the above example we simply present wasted human time and
>>> computational time due to an unnecessary synchronization with std::futu=
re,
>>> however a more complex system may indeed need their own future
>>> implementation which std::packaged_task cannot interoperate with at all=
..
>>> Comparison Table
>>>
>>> std::promise<Foo> p;
>>>
>>> std::unique_ptr<Foo> f;
>>>
>>> std::queue<std::function<void()>> a;
>>>
>>> std::queue<std::unique_function<void()>> b;
>>>
>>> using namespace std;
>>>
>>>
>>> Before Proposal
>>>
>>> After Proposal
>>>
>>> 1
>>>
>>> auto s =3D make_shared<Foo>(move(f));
>>> a.emplace([s] { s->work(); });
>>>
>>>
>>> // ...
>>>
>>> auto shared =3D a.top();
>>>
>>> shared();
>>>
>>> b.emplace([u =3D move(f)] {
>>>
>>> u->work();
>>>
>>> });
>>>
>>> // ...
>>>
>>> auto unique =3D move(b.top());
>>>
>>> unique();
>>>
>>> 2
>>>
>>> a.emplace([r =3D f.get()] {
>>>
>>> r->work();
>>>
>>> });
>>>
>>> b.emplace([u =3D move(f)] {
>>>
>>> u->work();
>>>
>>> });
>>>
>>> 3
>>>
>>> atomic<Foo*> result{nullptr};
>>>
>>> a.emplace([&result] {
>>>
>>> result =3D new Foo;
>>>
>>> });
>>> // ...
>>> spin_on(result);
>>> result->work();
>>>
>>> auto future =3D p.get_future();
>>>
>>> b.emplace([p =3D move(p)] {
>>>
>>> p.set_value(Foo{});
>>>
>>> });
>>>
>>> // ...
>>>
>>> future.get().work();
>>>
>>> As you can see, attempts to work around the limitation of std::function
>>> results in unacceptable undermining of uniqueness semantics, life-time
>>> safety, and/or ease of use:
>>>
>>> 1.
>>>
>>> Loss of move-only semantics and extra LoC and a heap allocation per
>>> shared pointer.
>>> 2.
>>>
>>> Queue lifetime must not exceed enclosing scope lifetime (or dangling
>>> pointer).
>>> 3.
>>>
>>> Poor usability or unnecessary complexity in search of better
>>> performance.
>>>
>>> Alternatives
>>>
>>> Papers =E2=80=9Cstd::function and Beyond=E2=80=9C N4159
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf>, =
=E2=80=9CA
>>> polymorphic wrapper for all Callable objects (rev. 3)=E2=80=9D P0288R1
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0288r1.pdf>
>>> have already argued for fixing std::function to support non-copyable ty=
pes
>>> (among other issues) some time ago. Yet it seems self evident that as l=
ong
>>> and as widely as std::function has been in use, any change that breaks =
the
>>> observable surface area of std::function is a non-starter. The question=
is
>>> would the use case we outlined herein, if overlaid onto the existing
>>> std::function, cause previously valid code to break, or conversely
>>> previously incorrect code to become easily written?
>>>
>>> Let=E2=80=99s assume we have a means of =E2=80=9Cfixing=E2=80=9D std::f=
unction to allow mixing
>>> of copy and move semantics. Clearly all existing code would continue to
>>> function as all existing target callable types are CopyConstructible an=
d
>>> CopyAssignable, but what if we mix erased instances with copy and move
>>> semantics? How should the following operations on std::function be defi=
ned
>>> in terms of their target callable types?
>>>
>>> Let=E2=80=99s temporarily ignore the details of memory management, and =
consider
>>> p to be the underlying pointer to the erased instance.
>>>
>>> std2::function<void()> c =3D C{}; // Copy-only
>>> std2::function<void()> m =3D M{}; // Move-only
>>>
>>>
>>> Operation
>>>
>>> Definition
>>>
>>> Result
>>>
>>> c =3D std::move(m);
>>>
>>> *((M*)c.p) =3D move(*((M*)m.p));
>>>
>>> Move
>>>
>>> m =3D std::move(c);
>>>
>>> *((C*)c.p) =3D move(*((C*)m.p));
>>>
>>> Copy
>>>
>>> c =3D m;
>>>
>>> *((M*)c.p) =3D *((M*)m.p);
>>>
>>> Throw ???
>>>
>>> m =3D c;
>>>
>>> *((C*)c.p) =3D *((C*)m.p);
>>>
>>> Copy
>>>
>>> Again we face an unacceptable undermining of uniqueness semantics; in
>>> addition we have changed the observable surface area of assignment by
>>> necessitating a new runtime error reporting mechanism for when erased
>>> targets conflicting behavior, affecting the exception-safety of existin=
g
>>> code.
>>> Shallow v. Deep Const
>>>
>>> =E2=80=9CShallow=E2=80=9D or =E2=80=9CDeep=E2=80=9D const in a type era=
sed context means whether the
>>> constness of the erasing type is extended towards the erased type. For =
our
>>> discussion we consider whether the the erasing container is const calla=
ble
>>> if and only if the underlying type is const callable.
>>>
>>>
>>> It is by now understood that the standard requires const correctness to
>>> imply thread-safety, and if the container operator() is const, the
>>> underlying callable type=E2=80=99s operator() must also be const in ord=
er to
>>> hope of satisfying this obligation. So a shallow const container could
>>> not admit a thread-safe call operation in general, and both N4159
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf> and
>>> P0045R1
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf>
>>> draw attention to the unfortunate outcome. The solution presented in th=
ose
>>> papers it to include the constness of the callable in signature, and to
>>> have the constness of container operator() be conditional on the signat=
ure.
>>>
>>> struct Accessor {
>>>
>>> void operator()() const;
>>>
>>> // ...
>>>
>>> } access;
>>>
>>> struct Mutator {
>>>
>>> void operator()();
>>>
>>> // ...
>>>
>>> } mutate;
>>>
>>> std3::function<void() const> a =3D access; // ok
>>>
>>> std3::function<void()> b =3D access; // ok
>>>
>>> std3::function<void()> c =3D mutate; // ok
>>>
>>> std3::function<void() const> d =3D mutate; // compile error
>>>
>>> a =3D b; // compile error: target type more restrictive
>>>
>>> b =3D a; // ok
>>>
>>> b =3D c; // ok
>>>
>>>
>>> This proposal, while in the author=E2=80=99s opinion is highly recommen=
ded
>>> improvement, it=E2=80=99s best presented in referenced papers, and for =
simplicity=E2=80=99s
>>> sake isn=E2=80=99t pursued further here.
>>>
>>> Otherwise, without the above but desiring deep const semantics, we woul=
d
>>> wish that const containers require const callable targets. However, sin=
ce
>>> we have erase the constness of target instance, we are left with throwi=
ng
>>> when deep const is violated, breaking existing exception-safe code.
>>>
>>> const std4::function<void()> a; // deep const
>>>
>>> std::function<void()> b =3D mutate; // non-const target
>>>
>>> a =3D b; // target copied
>>>
>>> a(); // now throws!
>>> Necessity and Cost
>>>
>>> We can all agree type erased containers should support as much as
>>> feasible the const correctness of its target types, but we began our
>>> argument with a specific asynchronous use case that involved deferred
>>> computations, often invoked on foreign threads. If this pattern as seen=
=E2=80=9Cin
>>> the wild=E2=80=9D makes use of thread safe queues, is thread safety of =
the
>>> container itself actually sufficient to justify the costs associated wi=
th
>>> extra synchronization or exception safety? Even if we can guarantee con=
st
>>> container only calls const target methods, we still cannot guarantee th=
e
>>> target itself makes the connection between const and thread safety.
>>>
>>> Should a proposed std::unique_function emulate =E2=80=9Cbroken=E2=80=9D=
shallow const
>>> correctness of std::function for uniformity, or is =E2=80=9Cfixing=E2=
=80=9D the
>>> contradiction worth breaking runtime changes? And is std::unique_/funct=
ion
>>> more like a container or pointer (where const is understood to be shall=
ow),
>>> or is it more like an opaque type (where const is generally considered =
to
>>> be deep)? Historically we allow container const to vary independently o=
f
>>> parameterized types when they exist, suggesting std::function should re=
main
>>> a shallow container.
>>>
>>> While this question is relevant to the specification of
>>> std::unique_function, it is ultimately orthogonal to the question of
>>> the need for std::unique_function to exist, which is this paper=E2=80=
=99s main
>>> concern.
>>> Conclusion
>>>
>>> So long as we have move-only lambdas and type erased callable
>>> containers, a move-only capable std::function is required. As uniquenes=
s
>>> semantics of container are orthogonal to const-correctness of the inter=
face
>>> we recommend not conflating the two, and pursuing P0045R1
>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf>
>>> for const-correctness as an independent feature request.
>>> References
>>>
>>> [1] https://reviews.llvm.org/D48349
>>>
>>> [2] http://llvm.org/doxygen/FunctionExtras_8h_source.html#l00046
>>>
>>> [3]
>>> https://github.com/STEllAR-GROUP/hpx/blob/master/hpx/util/unique_functi=
on.hpp
>>>
>>> [4]
>>> https://github.com/potswa/cxx_function/blob/master/cxx_function.hpp#L11=
92
>>>
>>> [5]
>>> https://github.com/Naios/function2/blob/master/include/function2/functi=
on2.hpp#L1406
>>>
>>> [6] https://github.com/facebook/folly/blob/master/folly/Function.h
>>>
>>> --
>>> 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/CAHn%2BA5N=
yaUQjAeudtObjn08Trz4iJ%2Bu-GGt2J5VnmtmZJiPVxg%40mail.gmail.com
>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHn%2BA5=
NyaUQjAeudtObjn08Trz4iJ%2Bu-GGt2J5VnmtmZJiPVxg%40mail.gmail.com?utm_medium=
=3Demail&utm_source=3Dfooter>
>>> .
>>>
>> --
>> You received this message because you are subscribed to the Google Group=
s
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> 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/CAJH_FNW1PV=
w2BeYJCWfKNKN3_67eLY_6wG1vgNJOZx9oQS%2Bs%3DQ%40mail.gmail.com
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJH_FNW1P=
Vw2BeYJCWfKNKN3_67eLY_6wG1vgNJOZx9oQS%2Bs%3DQ%40mail.gmail.com?utm_medium=
=3Demail&utm_source=3Dfooter>
>> .
>>
> --
> 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/CAHn%2BA5NHi=
EO1rTKfZOryWnW-NTqLGgim6epp-Bt03iU5wd-EEA%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHn%2BA5NH=
iEO1rTKfZOryWnW-NTqLGgim6epp-Bt03iU5wd-EEA%40mail.gmail.com?utm_medium=3Dem=
ail&utm_source=3Dfooter>
> .
>
--=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/CAJH_FNWs-rP4hc6V3pE1vTgQgtTUKfNsJOmOzsxWvwRzsC2=
ywA%40mail.gmail.com.
--0000000000004538e50578e7d491
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">From the minutes from the presentation of P0288 in Toronto=
it looks like there was a request for updated wording to make it independe=
nt of P0045, but otherwise little obvious concern. It seems likely that tha=
t's the important change to make.<div><br></div><div>Given the paper re=
ading load between now and SD we're going to be overwhelmed, I think. I=
'd be happy to give some feedback on a wording draft in the short term.=
</div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Tue, 23 Oct =
2018 at 09:18, Ryan McDougall <<a href=3D"mailto:mcdougall.ryan@gmail.co=
m">mcdougall.ryan@gmail.com</a>> wrote:<br></div><blockquote class=3D"gm=
ail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-le=
ft:1ex"><div dir=3D"ltr">Yes, I'll be at SD in order to push this paper=
-- thought I don't know if there's room on anyone schedule. I have=
hope however since it's relatively uncontroversial it can yet be fast =
tracked. I would very much like help with wording if you're available.<=
div><br></div><div>Cheers,</div></div><br><div class=3D"gmail_quote"><div d=
ir=3D"ltr">On Tue, Oct 23, 2018 at 9:14 AM Lee Howes <<a href=3D"mailto:=
xrikcus@gmail.com" target=3D"_blank">xrikcus@gmail.com</a>> wrote:<br></=
div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-lef=
t:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Hi Ryan,<div>Are you pl=
anning to attend the meeting and argue the case for unique_function? This i=
s something that came up again this week for us at Facebook as well, and wh=
ile we work around it with folly::Function as you noted, having to do so is=
not optimal. It would certainly be a good thing to get a unique_function i=
nto the standard soonish.</div><div><br></div><div>Lee Howes</div></div><br=
><div class=3D"gmail_quote"><div dir=3D"ltr">On Mon, 22 Oct 2018 at 11:19, =
Ryan McDougall <<a href=3D"mailto:mcdougall.ryan@gmail.com" target=3D"_b=
lank">mcdougall.ryan@gmail.com</a>> wrote:<br></div><blockquote class=3D=
"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding=
-left:1ex"><div dir=3D"ltr"><span id=3D"m_-2995601466636599522m_-1335907127=
606806884m_-3924309839588613576gmail-docs-internal-guid-def7cea7-7fff-bf6e-=
c2f3-4764896f986c"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;=
margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rg=
b(0,0,0);background-color:transparent;font-variant-numeric:normal;font-vari=
ant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">=E2=80=
=9CThis is motivated by increasing usage of things like executors and the t=
ask</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margi=
n-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0=
,0);background-color:transparent;font-variant-numeric:normal;font-variant-e=
ast-asian:normal;vertical-align:baseline;white-space:pre-wrap">queue where =
it is useful to embed move-only types like a std::promise within</span></p>=
<p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt">=
<span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background=
-color:transparent;font-variant-numeric:normal;font-variant-east-asian:norm=
al;vertical-align:baseline;white-space:pre-wrap">a type erased function. Th=
at isn't possible without this version of a type</span></p><p dir=3D"lt=
r" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap">erased function.=E2=80=9D -- Chandler=
Carruth[1]</span></p><h1 dir=3D"ltr" style=3D"line-height:1.38;margin-top:=
20pt;margin-bottom:6pt"><span style=3D"font-size:20pt;font-family:Arial;col=
or:rgb(0,0,0);background-color:transparent;font-weight:400;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap">Thanks</span></h1><p dir=3D"ltr" style=3D"line-height:1.38;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:A=
rial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:nor=
mal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-=
wrap">=E2=80=9Cstd::function and Beyond=E2=80=9C </span><a href=3D"http://w=
ww.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf" style=3D"text-de=
coration-line:none" target=3D"_blank"><span style=3D"font-size:11pt;font-fa=
mily:Arial;background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;text-decoration-line:underline;vertical-align:basel=
ine;white-space:pre-wrap">N4159</span></a><span style=3D"font-size:11pt;fon=
t-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-n=
umeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-=
space:pre-wrap">, =E2=80=9CQualified std::function Signatures=E2=80=9D </sp=
an><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045=
r1.pdf" style=3D"text-decoration-line:none" target=3D"_blank"><span style=
=3D"font-size:11pt;font-family:Arial;background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:unde=
rline;vertical-align:baseline;white-space:pre-wrap">P0045R1</span></a><span=
style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ve=
rtical-align:baseline;white-space:pre-wrap">, and =E2=80=9CA polymorphic wr=
apper for all Callable objects (rev. 3)=E2=80=9D </span><a href=3D"http://w=
ww.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0288r1.pdf" style=3D"text-=
decoration-line:none" target=3D"_blank"><span style=3D"font-size:11pt;font-=
family:Arial;background-color:transparent;font-variant-numeric:normal;font-=
variant-east-asian:normal;text-decoration-line:underline;vertical-align:bas=
eline;white-space:pre-wrap">P0288R1</span></a><span style=3D"font-size:11pt=
;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap"> et al. for laying the groundwork for this paper. Thank=
you to David Krauss and Arthur O=E2=80=99Dwyer for your discussion and fee=
dback. Thank you all authors of alternative type erased callable containers=
for your proof and inspiration.</span></p><h1 dir=3D"ltr" style=3D"line-he=
ight:1.38;margin-top:20pt;margin-bottom:6pt"><span style=3D"font-size:20pt;=
font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-weight=
:400;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-al=
ign:baseline;white-space:pre-wrap">Motivation</span></h1><p dir=3D"ltr" sty=
le=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"fon=
t-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent=
;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:=
baseline;white-space:pre-wrap">std::function models both CopyConstructible =
and CopyAssignable, and requires its erased target type to declare a copy c=
onstructor. This means std::function =C2=A0is hopelessly incompatible with =
std::unique_ptr, std::promise, or any other move-only type. This is a funct=
ional gap felt by C++ users to the degree that there=E2=80=99s some half-do=
zen popular and high-quality implementations available under the name =E2=
=80=9Cunique_function=E2=80=9D. [2][3][4][5][6]</span></p><br><p dir=3D"ltr=
" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap">C++ has many move-only vocabulary typ=
es, and when introduced they impose tighter constraints on the interface, a=
nd can become =E2=80=9Cviral=E2=80=9D -- causing any previously copyable pa=
ths to require move or forwarding operations. Consider</span></p><br><p dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span =
style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0=
);background-color:transparent;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;vertical-align:baseline;white-space:pre-wrap">class DbResult=
{</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin=
-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&qu=
ot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norm=
al;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-w=
rap"> private:</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-to=
p:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Co=
urier New";color:rgb(0,0,0);background-color:transparent;font-variant-=
numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white=
-space:pre-wrap"> =C2=A0std::unique_ptr<Blob> data_; =C2=A0// now req=
uired!</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;ma=
rgin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier Ne=
w";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap">};</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-t=
op:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"C=
ourier New";color:rgb(0,0,0);background-color:transparent;font-variant=
-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whit=
e-space:pre-wrap">class Reactor {</span></p><p dir=3D"ltr" style=3D"line-he=
ight:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;f=
ont-family:"Courier New";color:rgb(0,0,0);background-color:transp=
arent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-a=
lign:baseline;white-space:pre-wrap"> private:</span></p><p dir=3D"ltr" styl=
e=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font=
-size:11pt;font-family:"Courier New";color:rgb(0,0,0);background-=
color:transparent;font-variant-numeric:normal;font-variant-east-asian:norma=
l;vertical-align:baseline;white-space:pre-wrap"> =C2=A0std::map<std::str=
ing, std::function<void()>> reactions_;</span></p><p dir=3D"ltr" s=
tyle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"f=
ont-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap">};</span></p><br><p dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span =
style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0=
);background-color:transparent;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;vertical-align:baseline;white-space:pre-wrap">reactor.on_eve=
nt(=E2=80=9Cdb-result-ready=E2=80=9D, [&] {</span></p><p dir=3D"ltr" st=
yle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"fo=
nt-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgroun=
d-color:transparent;font-variant-numeric:normal;font-variant-east-asian:nor=
mal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0reactor.on_event(=
=E2=80=9Chas-towel=E2=80=9D, [result =3D std::move(db.result())] {</span></=
p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt=
"><span style=3D"font-size:11pt;font-family:"Courier New";color:r=
gb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-var=
iant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=
=A0=C2=A0=C2=A0auto meaning =3D find(result); // 42</span></p><p dir=3D"ltr=
" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0});</span></=
p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt=
"><span style=3D"font-size:11pt;font-family:"Courier New";color:r=
gb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-var=
iant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">});</s=
pan></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0=
);background-color:transparent;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;vertical-align:baseline;white-space:pre-wrap">It is not enou=
gh to simply std::move the DbResult into the lambda, as Reactor::on_event i=
s unable to assign to a move-only lambda as implemented with std::function.=
</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;marg=
in-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,=
0,0);background-color:transparent;font-variant-numeric:normal;font-variant-=
east-asian:normal;vertical-align:baseline;white-space:pre-wrap">This is a r=
ecurring pattern in much concurrent code, such as work queues, task graphs,=
or command buffers. The committee implicitly understood the need when it c=
reated std::packaged_task, also a type-erased polymorphic container, but th=
at type is tightly bound to std::futures, which may not be fit for purpose =
in any code base that doesn=E2=80=99t already rely on them.</span></p><br><=
p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><=
span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-=
color:transparent;font-variant-numeric:normal;font-variant-east-asian:norma=
l;vertical-align:baseline;white-space:pre-wrap">If we are developing</span>=
<span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background=
-color:transparent;font-style:italic;font-variant-numeric:normal;font-varia=
nt-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> any</sp=
an><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgro=
und-color:transparent;font-variant-numeric:normal;font-variant-east-asian:n=
ormal;vertical-align:baseline;white-space:pre-wrap"> kind of asynchronous w=
ork queue we need </span></p><ol style=3D"margin-top:0pt;margin-bottom:0pt"=
><li dir=3D"ltr" style=3D"list-style-type:upper-alpha;font-size:11pt;font-f=
amily:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-nume=
ric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spa=
ce:pre-wrap"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin=
-bottom:0pt"><span style=3D"font-size:11pt;background-color:transparent;fon=
t-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:base=
line;white-space:pre-wrap">inheritance based polymorphism (and a mechanism =
to manage heap allocated derived objects, such as std::shared_ptr)</span></=
p></li><li dir=3D"ltr" style=3D"list-style-type:upper-alpha;font-size:11pt;=
font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varian=
t-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whi=
te-space:pre-wrap"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;=
margin-bottom:0pt"><span style=3D"font-size:11pt;background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap">type-erased container with </span><span st=
yle=3D"font-size:11pt;background-color:transparent;font-style:italic;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">small object optimization</span><span style=3D"font=
-size:11pt;background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> like=
std::function (for copy-only callable types), std::packaged_task+std::futu=
re (for move-only callable types)</span></p></li></ol><br><p dir=3D"ltr" st=
yle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"fo=
nt-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap">However if any facet of our runtime preclud=
es use of std::future -- such as if it provides its own future type, or doe=
s not use futures at all, we are again left without the ability to use std:=
:unique_ptr or </span><span style=3D"font-size:11pt;font-family:Arial;color=
:rgb(0,0,0);background-color:transparent;font-weight:700;font-style:italic;=
font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:b=
aseline;white-space:pre-wrap">any other</span><span style=3D"font-size:11pt=
;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap"> non-copyable type.</span></p><br><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:"Courier New";color:rgb(0,0,0);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">auto unique =3D</span></p><p=
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0std=
::make_unique<BankTransfer>(=E2=80=9CDrEvil=E2=80=9D, 1000000000);</s=
pan></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">auto do_bank_transfer =3D</span></p><p dir=3D"ltr" style=3D"line-height=
:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-=
family:"Courier New";color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap"> =C2=A0[transfer =3D std::move(unique)] (Ba=
nk* to, Bank* from) {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&=
quot;Courier New";color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap"> =C2=A0=C2=A0=C2=A0return from->send(transfer, t=
o);</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margi=
n-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&q=
uot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:nor=
mal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-=
wrap">};</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:=
0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Cour=
ier New";color:rgb(0,0,0);background-color:transparent;font-variant-nu=
meric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-s=
pace:pre-wrap">ThreadSafeQueue<std::function<int()>> transactio=
ns1;</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;marg=
in-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&=
quot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre=
-wrap">transactions1.emplace(do_bank_transfer); =C2=A0// Compile Error!!</s=
pan></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">// ...</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-to=
p:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Co=
urier New";color:rgb(0,0,0);background-color:transparent;font-variant-=
numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white=
-space:pre-wrap">ThreadSafeQueue<std::packaged_task<int()>> tra=
nsactions2;</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0=
pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Couri=
er New";color:rgb(0,0,0);background-color:transparent;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap">ThreadSafeQueue<int> results</span></p><p dir=3D"ltr" s=
tyle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"f=
ont-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap">transactions2.emplace(do=
_bank_transfer);</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;mar=
gin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&q=
uot;Courier New";color:rgb(0,0,0);background-color:transparent;font-va=
riant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline=
;white-space:pre-wrap">hpy::async([&] {</span></p><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:"Courier New";color:rgb(0,0,0);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap"> =C2=A0while (!transactions2=
..empty()) {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0=
pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Couri=
er New";color:rgb(0,0,0);background-color:transparent;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap"> =C2=A0=C2=A0=C2=A0transactions2.top()();</span></p><p dir=3D=
"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span sty=
le=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);b=
ackground-color:transparent;font-variant-numeric:normal;font-variant-east-a=
sian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0=C2=A0=C2=
=A0results.push_back(transactions2.top().get_future()); // ??</span></p><p =
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><sp=
an style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,=
0,0);background-color:transparent;font-variant-numeric:normal;font-variant-=
east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0}</s=
pan></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bott=
om:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";c=
olor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fo=
nt-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">=
});</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;m=
argin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb=
(0,0,0);background-color:transparent;font-variant-numeric:normal;font-varia=
nt-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">In the a=
bove example we simply present wasted human time and computational time due=
to an unnecessary synchronization with std::future, however a more complex=
system may indeed need their own future implementation which std::packaged=
_task cannot interoperate with at all.</span></p><h1 dir=3D"ltr" style=3D"l=
ine-height:1.38;margin-top:20pt;margin-bottom:6pt"><span style=3D"font-size=
:20pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-=
weight:400;font-variant-numeric:normal;font-variant-east-asian:normal;verti=
cal-align:baseline;white-space:pre-wrap">Comparison Table</span></h1><p dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span =
style=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0=
);background-color:transparent;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;vertical-align:baseline;white-space:pre-wrap">std::promise&l=
t;Foo> p;</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:=
0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Cour=
ier New";color:rgb(0,0,0);background-color:transparent;font-variant-nu=
meric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-s=
pace:pre-wrap">std::unique_ptr<Foo> f;</span></p><p dir=3D"ltr" style=
=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-s=
ize:10pt;font-family:"Courier New";color:rgb(0,0,0);background-co=
lor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;=
vertical-align:baseline;white-space:pre-wrap">std::queue<std::function&l=
t;void()>> a;</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margi=
n-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:&quo=
t;Courier New";color:rgb(0,0,0);background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;w=
hite-space:pre-wrap">std::queue<std::unique_function<void()>> b=
;</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">using namespace std;</span></p><br><div dir=3D"ltr" style=3D"margin-lef=
t:0pt"><table style=3D"border:none;border-collapse:collapse"><colgroup><col=
width=3D"17"><col width=3D"295"><col width=3D"289"></colgroup><tbody><tr s=
tyle=3D"height:0pt"><td style=3D"border-width:1pt;border-style:solid;border=
-color:rgb(0,0,0);vertical-align:top;padding:5pt"><br></td><td style=3D"bor=
der-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top=
;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin=
-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,=
0);background-color:transparent;font-variant-numeric:normal;font-variant-ea=
st-asian:normal;vertical-align:baseline;white-space:pre-wrap">Before Propos=
al</span></p></td><td style=3D"border-width:1pt;border-style:solid;border-c=
olor:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"lin=
e-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11p=
t;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;w=
hite-space:pre-wrap">After Proposal</span></p></td></tr><tr style=3D"height=
:67pt"><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,=
0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.=
2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-fami=
ly:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric=
:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:=
pre-wrap">1</span></p></td><td style=3D"border-width:1pt;border-style:solid=
;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" sty=
le=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font=
-size:10pt;font-family:"Courier New";color:rgb(0,0,0);background-=
color:transparent;font-variant-numeric:normal;font-variant-east-asian:norma=
l;vertical-align:baseline;white-space:pre-wrap">auto s =3D make_shared<F=
oo>(move(f));</span><span style=3D"font-size:10pt;font-family:"Cour=
ier New";color:rgb(0,0,0);background-color:transparent;font-variant-nu=
meric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-s=
pace:pre-wrap"><br class=3D"m_-2995601466636599522m_-1335907127606806884m_-=
3924309839588613576gmail-kix-line-break"></span><span style=3D"font-size:10=
pt;font-family:"Courier New";color:rgb(0,0,0);background-color:tr=
ansparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertic=
al-align:baseline;white-space:pre-wrap">a.emplace([s] { s->work(); });</=
span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bott=
om:0pt"><span style=3D"font-size:10pt;font-family:"Courier New";c=
olor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fo=
nt-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">=
<br class=3D"m_-2995601466636599522m_-1335907127606806884m_-392430983958861=
3576gmail-kix-line-break"></span><span style=3D"font-size:10pt;font-family:=
"Courier New";color:rgb(0,0,0);background-color:transparent;font-=
variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseli=
ne;white-space:pre-wrap">// ...</span></p><p dir=3D"ltr" style=3D"line-heig=
ht:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font=
-family:"Courier New";color:rgb(0,0,0);background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap">auto shared =3D a.top();</span></p><p dir=
=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span s=
tyle=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0)=
;background-color:transparent;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap">shared();</span=
></p></td><td style=3D"border-width:1pt;border-style:solid;border-color:rgb=
(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height=
:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-f=
amily:"Courier New";color:rgb(0,0,0);background-color:transparent=
;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:=
baseline;white-space:pre-wrap">b.emplace([u =3D move(f)] {</span></p><p dir=
=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span s=
tyle=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0)=
;background-color:transparent;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0u->wo=
rk();</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;marg=
in-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New&=
quot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre=
-wrap">});</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt=
;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier=
New";color:rgb(0,0,0);background-color:transparent;font-variant-numer=
ic:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spac=
e:pre-wrap">// ...</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin=
-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"=
;Courier New";color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap">auto unique =3D move(b.top());</span></p><p dir=3D"ltr"=
style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"=
font-size:10pt;font-family:"Courier New";color:rgb(0,0,0);backgro=
und-color:transparent;font-variant-numeric:normal;font-variant-east-asian:n=
ormal;vertical-align:baseline;white-space:pre-wrap">unique();</span></p></t=
d></tr><tr style=3D"height:0pt"><td style=3D"border-width:1pt;border-style:=
solid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr=
" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D=
"font-size:10pt;font-family:Arial;color:rgb(0,0,0);background-color:transpa=
rent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-al=
ign:baseline;white-space:pre-wrap">2</span></p></td><td style=3D"border-wid=
th:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;paddin=
g:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom=
:0pt"><span style=3D"font-size:10pt;font-family:"Courier New";col=
or:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font=
-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">a.=
emplace([r =3D f.get()] {</span></p><p dir=3D"ltr" style=3D"line-height:1.2=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-famil=
y:"Courier New";color:rgb(0,0,0);background-color:transparent;fon=
t-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:base=
line;white-space:pre-wrap"> =C2=A0r->work();</span></p><p dir=3D"ltr" st=
yle=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"fon=
t-size:10pt;font-family:"Courier New";color:rgb(0,0,0);background=
-color:transparent;font-variant-numeric:normal;font-variant-east-asian:norm=
al;vertical-align:baseline;white-space:pre-wrap">});</span></p></td><td sty=
le=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-=
align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0=
pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Couri=
er New";color:rgb(0,0,0);background-color:transparent;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap">b.emplace([u =3D move(f)] {</span></p><p dir=3D"ltr" style=3D=
"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size=
:10pt;font-family:"Courier New";color:rgb(0,0,0);background-color=
:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap"> =C2=A0u->work();</span></p><=
p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:10pt;font-family:"Courier New";color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">});</span>=
</p></td></tr><tr style=3D"height:0pt"><td style=3D"border-width:1pt;border=
-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=
=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span s=
tyle=3D"font-size:10pt;font-family:Arial;color:rgb(0,0,0);background-color:=
transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vert=
ical-align:baseline;white-space:pre-wrap">3</span></p></td><td style=3D"bor=
der-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top=
;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin=
-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New&qu=
ot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norm=
al;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-w=
rap">atomic<Foo*> result{nullptr};</span></p><p dir=3D"ltr" style=3D"=
line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:=
10pt;font-family:"Courier New";color:rgb(0,0,0);background-color:=
transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vert=
ical-align:baseline;white-space:pre-wrap">a.emplace([&result] {</span><=
/p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt=
"><span style=3D"font-size:10pt;font-family:"Courier New";color:r=
gb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-var=
iant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=
=A0result =3D new Foo;</span></p><p dir=3D"ltr" style=3D"line-height:1.2;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:&=
quot;Courier New";color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">});</span><span style=3D"font-size:10pt;font-family=
:"Courier New";color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap"><br class=3D"m_-2995601466636599522m_-13359071276=
06806884m_-3924309839588613576gmail-kix-line-break"></span><span style=3D"f=
ont-size:10pt;font-family:"Courier New";color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap">// ...</span><span style=
=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap"><br class=3D"m_-299=
5601466636599522m_-1335907127606806884m_-3924309839588613576gmail-kix-line-=
break"></span><span style=3D"font-size:10pt;font-family:"Courier New&q=
uot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:nor=
mal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-=
wrap">spin_on(result);</span><span style=3D"font-size:10pt;font-family:&quo=
t;Courier New";color:rgb(0,0,0);background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;w=
hite-space:pre-wrap"><br class=3D"m_-2995601466636599522m_-1335907127606806=
884m_-3924309839588613576gmail-kix-line-break"></span><span style=3D"font-s=
ize:10pt;font-family:"Courier New";color:rgb(0,0,0);background-co=
lor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;=
vertical-align:baseline;white-space:pre-wrap">result->work();</span></p>=
</td><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,=
0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;=
margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family=
:"Courier New";color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap">auto future =3D p.get_future();</span></p><p dir=
=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span s=
tyle=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0)=
;background-color:transparent;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap">b.emplace([p =
=3D move(p)] {</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top=
:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Cou=
rier New";color:rgb(0,0,0);background-color:transparent;font-variant-n=
umeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-=
space:pre-wrap"> =C2=A0p.set_value(Foo{});</span></p><p dir=3D"ltr" style=
=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-s=
ize:10pt;font-family:"Courier New";color:rgb(0,0,0);background-co=
lor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;=
vertical-align:baseline;white-space:pre-wrap">});</span></p><p dir=3D"ltr" =
style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"f=
ont-size:10pt;font-family:"Courier New";color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap">// ...</span></p><p dir=
=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span s=
tyle=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0)=
;background-color:transparent;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap">future.get().wo=
rk();</span></p></td></tr></tbody></table></div><br><p dir=3D"ltr" style=3D=
"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-siz=
e:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap">As you can see, attempts to work around the limit=
ation of std::function results in unacceptable undermining of uniqueness se=
mantics, life-time safety, and/or ease of use:</span></p><ol style=3D"margi=
n-top:0pt;margin-bottom:0pt"><li dir=3D"ltr" style=3D"list-style-type:decim=
al;font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:trans=
parent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-=
align:baseline;white-space:pre-wrap"><p dir=3D"ltr" style=3D"line-height:1.=
38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap">Loss of move-only semant=
ics and extra LoC and a heap allocation per shared pointer.</span></p></li>=
<li dir=3D"ltr" style=3D"list-style-type:decimal;font-size:11pt;font-family=
:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pr=
e-wrap"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bott=
om:0pt"><span style=3D"font-size:11pt;background-color:transparent;font-var=
iant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;=
white-space:pre-wrap">Queue lifetime must not exceed enclosing scope lifeti=
me (or dangling pointer).</span></p></li><li dir=3D"ltr" style=3D"list-styl=
e-type:decimal;font-size:11pt;font-family:Arial;color:rgb(0,0,0);background=
-color:transparent;font-variant-numeric:normal;font-variant-east-asian:norm=
al;vertical-align:baseline;white-space:pre-wrap"><p dir=3D"ltr" style=3D"li=
ne-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
1pt;background-color:transparent;font-variant-numeric:normal;font-variant-e=
ast-asian:normal;vertical-align:baseline;white-space:pre-wrap">Poor usabili=
ty or unnecessary complexity in search of better performance.</span></p></l=
i></ol><h1 dir=3D"ltr" style=3D"line-height:1.38;margin-top:20pt;margin-bot=
tom:6pt"><span style=3D"font-size:20pt;font-family:Arial;color:rgb(0,0,0);b=
ackground-color:transparent;font-weight:400;font-variant-numeric:normal;fon=
t-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">A=
lternatives</span></h1><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:=
0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;colo=
r:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-=
variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Pap=
ers =E2=80=9Cstd::function and Beyond=E2=80=9C </span><a href=3D"http://www=
..open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf" style=3D"text-deco=
ration-line:none" target=3D"_blank"><span style=3D"font-size:11pt;font-fami=
ly:Arial;background-color:transparent;font-variant-numeric:normal;font-vari=
ant-east-asian:normal;text-decoration-line:underline;vertical-align:baselin=
e;white-space:pre-wrap">N4159</span></a><span style=3D"font-size:11pt;font-=
family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap">, =E2=80=9CA polymorphic wrapper for all Callable objects (re=
v. 3)=E2=80=9D </span><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/doc=
s/papers/2017/p0288r1.pdf" style=3D"text-decoration-line:none" target=3D"_b=
lank"><span style=3D"font-size:11pt;font-family:Arial;background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;text-dec=
oration-line:underline;vertical-align:baseline;white-space:pre-wrap">P0288R=
1</span></a><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0=
);background-color:transparent;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;vertical-align:baseline;white-space:pre-wrap"> have already =
argued for fixing std::function to support non-copyable types (among other =
issues) some time ago. Yet it seems self evident that as long and as widely=
as std::function has been in use, any change that breaks the observable su=
rface area of std::function is a non-starter. The question is would the use=
case we outlined herein, if overlaid onto the existing std::function, caus=
e previously valid code to break, or conversely previously incorrect code t=
o become easily written?</span></p><br><p dir=3D"ltr" style=3D"line-height:=
1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-f=
amily:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-nume=
ric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spa=
ce:pre-wrap">Let=E2=80=99s assume we have a means of =E2=80=9Cfixing=E2=80=
=9D std::function to allow mixing of copy and move semantics. Clearly all e=
xisting code would continue to function as all existing target callable typ=
es are CopyConstructible and CopyAssignable, but what if we mix erased inst=
ances with copy and move semantics? How should the following operations on =
std::function be defined in terms of their target callable types?</span></p=
><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:=
0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backg=
round-color:transparent;font-variant-numeric:normal;font-variant-east-asian=
:normal;vertical-align:baseline;white-space:pre-wrap">Let=E2=80=99s tempora=
rily ignore the details of memory management, and consider </span><span sty=
le=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);b=
ackground-color:transparent;font-variant-numeric:normal;font-variant-east-a=
sian:normal;vertical-align:baseline;white-space:pre-wrap">p</span><span sty=
le=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tr=
ansparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertic=
al-align:baseline;white-space:pre-wrap"> to be the underlying pointer to th=
e erased instance.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;m=
argin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:=
"Courier New";color:rgb(0,0,0);background-color:transparent;font-=
variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseli=
ne;white-space:pre-wrap">std2::function<void()> c =3D C{}; // Copy-on=
ly</span><span style=3D"font-size:11pt;font-family:"Courier New";=
color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;f=
ont-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"=
><br class=3D"m_-2995601466636599522m_-1335907127606806884m_-39243098395886=
13576gmail-kix-line-break"></span><span style=3D"font-size:11pt;font-family=
:"Courier New";color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap">std2::function<void()> m =3D M{}; // Move-o=
nly</span></p><br><br><div dir=3D"ltr" style=3D"margin-left:0pt"><table sty=
le=3D"border:none;border-collapse:collapse"><colgroup><col width=3D"163"><c=
ol width=3D"276"><col width=3D"166"></colgroup><tbody><tr style=3D"height:0=
pt"><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0=
);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;=
margin-top:0pt;margin-bottom:0pt;text-align:center"><span style=3D"font-siz=
e:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap">Operation</span></p></td><td style=3D"border-widt=
h:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding=
:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom=
:0pt;text-align:center"><span style=3D"font-size:11pt;font-family:Arial;col=
or:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font=
-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">De=
finition</span></p></td><td style=3D"border-width:1pt;border-style:solid;bo=
rder-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt;text-align:center"><s=
pan style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">Result</span></p></td></tr><=
tr style=3D"height:0pt"><td style=3D"border-width:1pt;border-style:solid;bo=
rder-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:"Courier New";color:rgb(0,0,0);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">c =3D std::move(m);</span></=
p></td><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,=
0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.=
38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-fam=
ily:"Courier New";color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">*((M*)c.p) =3D move(*((M*)m.p));</span></p></t=
d><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);=
vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;ma=
rgin-top:0pt;margin-bottom:0pt;text-align:center"><span style=3D"font-size:=
11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">Move</span></p></td></tr><tr style=3D"height:0pt"><=
td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);ver=
tical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margi=
n-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&quo=
t;Courier New";color:rgb(0,0,0);background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;w=
hite-space:pre-wrap">m =3D std::move(c);</span></p></td><td style=3D"border=
-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;pa=
dding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-b=
ottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New"=
;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal=
;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wra=
p">*((C*)c.p) =3D move(*((C*)m.p));</span></p></td><td style=3D"border-widt=
h:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding=
:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom=
:0pt;text-align:center"><span style=3D"font-size:11pt;font-family:Arial;col=
or:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font=
-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Co=
py</span></p></td></tr><tr style=3D"height:0pt"><td style=3D"border-width:1=
pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5p=
t"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0p=
t"><span style=3D"font-size:11pt;font-family:"Courier New";color:=
rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">c =3D=
m;</span></p></td><td style=3D"border-width:1pt;border-style:solid;border-=
color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"li=
ne-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
1pt;font-family:"Courier New";color:rgb(153,153,153);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">*((M*)c.p) =3D *((M*)m.p);</=
span></p></td><td style=3D"border-width:1pt;border-style:solid;border-color=
:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-he=
ight:1.38;margin-top:0pt;margin-bottom:0pt;text-align:center"><span style=
=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap">Throw ???</span></p></td></tr><tr sty=
le=3D"height:0pt"><td style=3D"border-width:1pt;border-style:solid;border-c=
olor:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"lin=
e-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11=
pt;font-family:"Courier New";color:rgb(0,0,0);background-color:tr=
ansparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertic=
al-align:baseline;white-space:pre-wrap">m =3D c;</span></p></td><td style=
=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-al=
ign:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0p=
t;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courie=
r New";color:rgb(0,0,0);background-color:transparent;font-variant-nume=
ric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spa=
ce:pre-wrap">*((C*)c.p) =3D *((C*)m.p);</span></p></td><td style=3D"border-=
width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;pad=
ding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bo=
ttom:0pt;text-align:center"><span style=3D"font-size:11pt;font-family:Arial=
;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;=
font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap=
">Copy</span></p></td></tr></tbody></table></div><br><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">Again we face an unacceptable undermining of u=
niqueness semantics; in addition we have changed the observable surface are=
a of assignment by necessitating a new runtime error reporting mechanism fo=
r when erased targets conflicting behavior, affecting the exception-safety =
of existing code.</span></p><h2 dir=3D"ltr" style=3D"line-height:1.38;margi=
n-top:18pt;margin-bottom:6pt"><span style=3D"font-size:16pt;font-family:Ari=
al;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap">Shallow v. Deep Const</span></h2><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">=E2=80=9CShallow=E2=80=9D or =E2=80=9CDeep=E2=
=80=9D const in a type erased context means whether the constness of the er=
asing type is extended towards the erased type. For our discussion we consi=
der whether the the erasing container is const callable if and only if the =
underlying type is const callable.</span></p><p dir=3D"ltr" style=3D"line-h=
eight:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;=
font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varian=
t-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whi=
te-space:pre-wrap"><br class=3D"m_-2995601466636599522m_-133590712760680688=
4m_-3924309839588613576gmail-kix-line-break"></span><span style=3D"font-siz=
e:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap">It is by now understood that the standard require=
s const correctness to imply thread-safety, and if the container operator()=
is const, the underlying callable type=E2=80=99s operator() must also be c=
onst in order to </span><span style=3D"font-size:11pt;font-family:Arial;col=
or:rgb(0,0,0);background-color:transparent;font-style:italic;font-variant-n=
umeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-=
space:pre-wrap">hope</span><span style=3D"font-size:11pt;font-family:Arial;=
color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;f=
ont-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"=
> of satisfying this obligation. So a shallow const container could not adm=
it a thread-safe call operation in general, and both </span><a href=3D"http=
://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf" style=3D"tex=
t-decoration-line:none" target=3D"_blank"><span style=3D"font-size:11pt;fon=
t-family:Arial;background-color:transparent;font-variant-numeric:normal;fon=
t-variant-east-asian:normal;text-decoration-line:underline;vertical-align:b=
aseline;white-space:pre-wrap">N4159</span></a><span style=3D"font-size:11pt=
;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap"> and </span><a href=3D"http://www.open-std.org/jtc1/sc2=
2/wg21/docs/papers/2017/p0045r1.pdf" style=3D"text-decoration-line:none" ta=
rget=3D"_blank"><span style=3D"font-size:11pt;font-family:Arial;background-=
color:transparent;font-variant-numeric:normal;font-variant-east-asian:norma=
l;text-decoration-line:underline;vertical-align:baseline;white-space:pre-wr=
ap">P0045R1</span></a><span style=3D"font-size:11pt;font-family:Arial;color=
:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> dra=
w attention to the unfortunate outcome. The solution presented in those pap=
ers it to include the constness of the callable in signature, and to have t=
he constness of container operator() be conditional on the signature.</span=
><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgroun=
d-color:transparent;font-variant-numeric:normal;font-variant-east-asian:nor=
mal;vertical-align:baseline;white-space:pre-wrap"><br class=3D"m_-299560146=
6636599522m_-1335907127606806884m_-3924309839588613576gmail-kix-line-break"=
><br class=3D"m_-2995601466636599522m_-1335907127606806884m_-39243098395886=
13576gmail-kix-line-break"></span></p><p dir=3D"ltr" style=3D"line-height:1=
..38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-fa=
mily:"Courier New";color:rgb(0,0,0);background-color:transparent;=
font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:b=
aseline;white-space:pre-wrap">struct Accessor {</span></p><p dir=3D"ltr" st=
yle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"fo=
nt-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgroun=
d-color:transparent;font-variant-numeric:normal;font-variant-east-asian:nor=
mal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0void operator()() =
const;</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;ma=
rgin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier Ne=
w";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap"> =C2=A0// ...</span></p><p dir=3D"ltr" style=3D"line-height:1.38;m=
argin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:=
"Courier New";color:rgb(0,0,0);background-color:transparent;font-=
variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseli=
ne;white-space:pre-wrap">} access;</span></p><br><p dir=3D"ltr" style=3D"li=
ne-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
1pt;font-family:"Courier New";color:rgb(0,0,0);background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;verti=
cal-align:baseline;white-space:pre-wrap">struct Mutator {</span></p><p dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span =
style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0=
);background-color:transparent;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0void op=
erator()();</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0=
pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Couri=
er New";color:rgb(0,0,0);background-color:transparent;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap"> =C2=A0// ...</span></p><p dir=3D"ltr" style=3D"line-height:1=
..38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-fa=
mily:"Courier New";color:rgb(0,0,0);background-color:transparent;=
font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:b=
aseline;white-space:pre-wrap">} mutate;</span></p><br><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:"Courier New";color:rgb(0,0,0);background-c=
olor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal=
;vertical-align:baseline;white-space:pre-wrap">std3::function<void() con=
st> a =3D access; =C2=A0// ok</span></p><p dir=3D"ltr" style=3D"line-hei=
ght:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;fo=
nt-family:"Courier New";color:rgb(0,0,0);background-color:transpa=
rent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-al=
ign:baseline;white-space:pre-wrap">std3::function<void()> b =3D acces=
s; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// ok</span></p><p dir=3D"ltr"=
style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D=
"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgr=
ound-color:transparent;font-variant-numeric:normal;font-variant-east-asian:=
normal;vertical-align:baseline;white-space:pre-wrap">std3::function<void=
()> c =3D mutate; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// ok</span>=
</p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0=
pt"><span style=3D"font-size:11pt;font-family:"Courier New";color=
:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">std3=
::function<void() const> d =3D mutate; =C2=A0// compile error</span><=
/p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-botto=
m:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";co=
lor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fon=
t-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">a=
=3D b; =C2=A0// compile error: target type more restrictive</span></p><p d=
ir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><spa=
n style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0=
,0);background-color:transparent;font-variant-numeric:normal;font-variant-e=
ast-asian:normal;vertical-align:baseline;white-space:pre-wrap">b =3D a; =C2=
=A0// ok</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;=
margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier =
New";color:rgb(0,0,0);background-color:transparent;font-variant-numeri=
c:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space=
:pre-wrap">b =3D c; =C2=A0// ok</span></p><p dir=3D"ltr" style=3D"line-heig=
ht:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;fon=
t-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-n=
umeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-=
space:pre-wrap"><br class=3D"m_-2995601466636599522m_-1335907127606806884m_=
-3924309839588613576gmail-kix-line-break"></span><span style=3D"font-size:1=
1pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-va=
riant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline=
;white-space:pre-wrap">This proposal, while in the author=E2=80=99s opinion=
is highly recommended improvement, it=E2=80=99s best presented in referenc=
ed papers, and for simplicity=E2=80=99s sake isn=E2=80=99t pursued further =
here.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt=
;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:r=
gb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-var=
iant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Otherw=
ise, without the above but desiring deep const semantics, we would wish tha=
t const containers require const callable targets. However, since we have e=
rase the constness of target instance, we are left with throwing when deep =
const is violated, breaking existing exception-safe code.</span></p><br><p =
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><sp=
an style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,=
0,0);background-color:transparent;font-variant-numeric:normal;font-variant-=
east-asian:normal;vertical-align:baseline;white-space:pre-wrap">const std4:=
:function<void()> a; =C2=A0=C2=A0=C2=A0// deep const</span></p><p dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span =
style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0=
);background-color:transparent;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;vertical-align:baseline;white-space:pre-wrap">std::function&=
lt;void()> b =3D mutate; =C2=A0// non-const target</span></p><p dir=3D"l=
tr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap">a =3D b; =C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0// target copied</span></p><p dir=3D"ltr" style=3D"line-height:1.2=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-famil=
y:"Courier New";color:rgb(0,0,0);background-color:transparent;fon=
t-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:base=
line;white-space:pre-wrap">a(); =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// now throw=
s!</span></p><h2 dir=3D"ltr" style=3D"line-height:1.38;margin-top:18pt;marg=
in-bottom:6pt"><span style=3D"font-size:16pt;font-family:Arial;color:rgb(0,=
0,0);background-color:transparent;font-weight:400;font-variant-numeric:norm=
al;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-w=
rap">Necessity and Cost</span></h2><p dir=3D"ltr" style=3D"line-height:1.38=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-famil=
y:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap">We can all agree type erased containers should support as much as =
feasible the const correctness of its target types, but we began our argume=
nt with a specific asynchronous use case that involved deferred computation=
s, often invoked on foreign threads. If this pattern as seen =E2=80=9Cin th=
e wild=E2=80=9D makes use of thread safe queues, is thread safety of the co=
ntainer itself actually sufficient to justify the costs associated with ext=
ra synchronization or exception safety? Even if we can guarantee const cont=
ainer only calls const target methods, we still cannot guarantee the target=
itself makes the connection between const and thread safety.</span></p><br=
><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"=
><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgroun=
d-color:transparent;font-variant-numeric:normal;font-variant-east-asian:nor=
mal;vertical-align:baseline;white-space:pre-wrap">Should a proposed std::un=
ique_function emulate =E2=80=9Cbroken=E2=80=9D shallow const correctness of=
std::function for uniformity, or is =E2=80=9Cfixing=E2=80=9D the contradic=
tion worth breaking runtime changes? And is std::unique_/function more like=
a container or pointer (where const is understood to be shallow), or is it=
more like an opaque type (where const is generally considered to be deep)?=
Historically we allow container const to vary independently of parameteriz=
ed types when they exist, suggesting std::function should remain a shallow =
container.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-to=
p:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;co=
lor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fon=
t-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">W=
hile this question is relevant to the specification of std::unique_function=
, it is ultimately </span><span style=3D"font-size:11pt;font-family:Arial;c=
olor:rgb(0,0,0);background-color:transparent;font-style:italic;font-variant=
-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whit=
e-space:pre-wrap">orthogonal</span><span style=3D"font-size:11pt;font-famil=
y:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap"> to the question of the need for std::unique_function to exist, wh=
ich is this paper=E2=80=99s main concern.</span></p><h1 dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:20pt;margin-bottom:6pt"><span style=3D"font=
-size:20pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;=
font-weight:400;font-variant-numeric:normal;font-variant-east-asian:normal;=
vertical-align:baseline;white-space:pre-wrap">Conclusion</span></h1><p dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span =
style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color=
:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap">So long as we have move-only lam=
bdas and type erased callable containers, a move-only capable std::function=
is required. As uniqueness semantics of container are orthogonal to const-=
correctness of the interface we recommend not conflating the two, and pursu=
ing </span><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/20=
17/p0045r1.pdf" style=3D"text-decoration-line:none" target=3D"_blank"><span=
style=3D"font-size:11pt;font-family:Arial;background-color:transparent;fon=
t-variant-numeric:normal;font-variant-east-asian:normal;text-decoration-lin=
e:underline;vertical-align:baseline;white-space:pre-wrap">P0045R1</span></a=
><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgroun=
d-color:transparent;font-variant-numeric:normal;font-variant-east-asian:nor=
mal;vertical-align:baseline;white-space:pre-wrap"> for const-correctness as=
an independent feature request.</span></p><h1 dir=3D"ltr" style=3D"line-he=
ight:1.38;margin-top:20pt;margin-bottom:6pt"><span style=3D"font-size:20pt;=
font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-weight=
:400;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-al=
ign:baseline;white-space:pre-wrap">References</span></h1><p dir=3D"ltr" sty=
le=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"fon=
t-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent=
;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:=
baseline;white-space:pre-wrap">[1] </span><a href=3D"https://reviews.llvm.o=
rg/D48349" style=3D"text-decoration-line:none" target=3D"_blank"><span styl=
e=3D"font-size:11pt;font-family:Arial;background-color:transparent;font-var=
iant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:und=
erline;vertical-align:baseline;white-space:pre-wrap">https://reviews.llvm.o=
rg/D48349</span></a></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top=
:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;col=
or:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font=
-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">[2=
] </span><a href=3D"http://llvm.org/doxygen/FunctionExtras_8h_source.html#l=
00046" style=3D"text-decoration-line:none" target=3D"_blank"><span style=3D=
"font-size:11pt;font-family:Arial;background-color:transparent;font-variant=
-numeric:normal;font-variant-east-asian:normal;text-decoration-line:underli=
ne;vertical-align:baseline;white-space:pre-wrap">http://llvm.org/doxygen/Fu=
nctionExtras_8h_source.html#l00046</span></a><span style=3D"font-size:11pt;=
font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varian=
t-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whi=
te-space:pre-wrap"> </span></p><p dir=3D"ltr" style=3D"line-height:1.38;mar=
gin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Ar=
ial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norm=
al;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-w=
rap">[3] </span><a href=3D"https://github.com/STEllAR-GROUP/hpx/blob/master=
/hpx/util/unique_function.hpp" style=3D"text-decoration-line:none" target=
=3D"_blank"><span style=3D"font-size:11pt;font-family:Arial;background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;te=
xt-decoration-line:underline;vertical-align:baseline;white-space:pre-wrap">=
https://github.com/STEllAR-GROUP/hpx/blob/master/hpx/util/unique_function.h=
pp</span></a></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;ma=
rgin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(=
0,0,0);background-color:transparent;font-variant-numeric:normal;font-varian=
t-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">[4] </spa=
n><a href=3D"https://github.com/potswa/cxx_function/blob/master/cxx_functio=
n.hpp#L1192" style=3D"text-decoration-line:none" target=3D"_blank"><span st=
yle=3D"font-size:11pt;font-family:Arial;background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:u=
nderline;vertical-align:baseline;white-space:pre-wrap">https://github.com/p=
otswa/cxx_function/blob/master/cxx_function.hpp#L1192</span></a><span style=
=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap"> </span></p><p dir=3D"ltr" style=3D"l=
ine-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:=
11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">[5] </span><a href=3D"https://github.com/Naios/func=
tion2/blob/master/include/function2/function2.hpp#L1406" style=3D"text-deco=
ration-line:none" target=3D"_blank"><span style=3D"font-size:11pt;font-fami=
ly:Arial;background-color:transparent;font-variant-numeric:normal;font-vari=
ant-east-asian:normal;text-decoration-line:underline;vertical-align:baselin=
e;white-space:pre-wrap">https://github.com/Naios/function2/blob/master/incl=
ude/function2/function2.hpp#L1406</span></a><span style=3D"font-size:11pt;f=
ont-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant=
-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whit=
e-space:pre-wrap"> </span></p><p dir=3D"ltr" style=3D"line-height:1.38;marg=
in-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Ari=
al;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">[6] </span><a href=3D"https://github.com/facebook/folly/blob/master/fol=
ly/Function.h" style=3D"text-decoration-line:none" target=3D"_blank"><span =
style=3D"font-size:11pt;font-family:Arial;background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;text-decoration-line=
:underline;vertical-align:baseline;white-space:pre-wrap">https://github.com=
/facebook/folly/blob/master/folly/Function.h</span></a><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap"> </span></p></span><br class=3D"m_-29956014666=
36599522m_-1335907127606806884m_-3924309839588613576gmail-Apple-interchange=
-newline"></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" target=3D"_=
blank">std-proposals+unsubscribe@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/CAHn%2BA5NyaUQjAeudtObjn08Trz4iJ%2Bu-=
GGt2J5VnmtmZJiPVxg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-p=
roposals/CAHn%2BA5NyaUQjAeudtObjn08Trz4iJ%2Bu-GGt2J5VnmtmZJiPVxg%40mail.gma=
il.com</a>.<br>
</blockquote></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" target=3D"_=
blank">std-proposals+unsubscribe@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/CAJH_FNW1PVw2BeYJCWfKNKN3_67eLY_6wG1v=
gNJOZx9oQS%2Bs%3DQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-p=
roposals/CAJH_FNW1PVw2BeYJCWfKNKN3_67eLY_6wG1vgNJOZx9oQS%2Bs%3DQ%40mail.gma=
il.com</a>.<br>
</blockquote></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" target=3D"_=
blank">std-proposals+unsubscribe@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/CAHn%2BA5NHiEO1rTKfZOryWnW-NTqLGgim6e=
pp-Bt03iU5wd-EEA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-pro=
posals/CAHn%2BA5NHiEO1rTKfZOryWnW-NTqLGgim6epp-Bt03iU5wd-EEA%40mail.gmail.c=
om</a>.<br>
</blockquote></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/CAJH_FNWs-rP4hc6V3pE1vTgQgtTUKfNsJOmO=
zsxWvwRzsC2ywA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">htt=
ps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJH_FNWs-rP4hc6V=
3pE1vTgQgtTUKfNsJOmOzsxWvwRzsC2ywA%40mail.gmail.com</a>.<br />
--0000000000004538e50578e7d491--
.
Author: Ryan McDougall <mcdougall.ryan@gmail.com>
Date: Tue, 23 Oct 2018 09:32:04 -0700
Raw View
--000000000000b52ed10578e7e979
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
I reference P0045, but my paper is independent. Essentially "we need this,
it's kind of obvious, let's decide if it's like std::function or "fixed" by
P0045".
If you or your team will be at SD we can bang out some wording in an hour I
feel.
On Tue, Oct 23, 2018 at 9:26 AM Lee Howes <xrikcus@gmail.com> wrote:
> From the minutes from the presentation of P0288 in Toronto it looks like
> there was a request for updated wording to make it independent of P0045,
> but otherwise little obvious concern. It seems likely that that's the
> important change to make.
>
> Given the paper reading load between now and SD we're going to be
> overwhelmed, I think. I'd be happy to give some feedback on a wording dra=
ft
> in the short term.
>
> On Tue, 23 Oct 2018 at 09:18, Ryan McDougall <mcdougall.ryan@gmail.com>
> wrote:
>
>> Yes, I'll be at SD in order to push this paper -- thought I don't know i=
f
>> there's room on anyone schedule. I have hope however since it's relative=
ly
>> uncontroversial it can yet be fast tracked. I would very much like help
>> with wording if you're available.
>>
>> Cheers,
>>
>> On Tue, Oct 23, 2018 at 9:14 AM Lee Howes <xrikcus@gmail.com> wrote:
>>
>>> Hi Ryan,
>>> Are you planning to attend the meeting and argue the case for
>>> unique_function? This is something that came up again this week for us =
at
>>> Facebook as well, and while we work around it with folly::Function as y=
ou
>>> noted, having to do so is not optimal. It would certainly be a good thi=
ng
>>> to get a unique_function into the standard soonish.
>>>
>>> Lee Howes
>>>
>>> On Mon, 22 Oct 2018 at 11:19, Ryan McDougall <mcdougall.ryan@gmail.com>
>>> wrote:
>>>
>>>> =E2=80=9CThis is motivated by increasing usage of things like executor=
s and the
>>>> task
>>>>
>>>> queue where it is useful to embed move-only types like a std::promise
>>>> within
>>>>
>>>> a type erased function. That isn't possible without this version of a
>>>> type
>>>>
>>>> erased function.=E2=80=9D -- Chandler Carruth[1]
>>>> Thanks
>>>>
>>>> =E2=80=9Cstd::function and Beyond=E2=80=9C N4159
>>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf>,
>>>> =E2=80=9CQualified std::function Signatures=E2=80=9D P0045R1
>>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf>,
>>>> and =E2=80=9CA polymorphic wrapper for all Callable objects (rev. 3)=
=E2=80=9D P0288R1
>>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0288r1.pdf>
>>>> et al. for laying the groundwork for this paper. Thank you to David Kr=
auss
>>>> and Arthur O=E2=80=99Dwyer for your discussion and feedback. Thank you=
all authors
>>>> of alternative type erased callable containers for your proof and
>>>> inspiration.
>>>> Motivation
>>>>
>>>> std::function models both CopyConstructible and CopyAssignable, and
>>>> requires its erased target type to declare a copy constructor. This me=
ans
>>>> std::function is hopelessly incompatible with std::unique_ptr,
>>>> std::promise, or any other move-only type. This is a functional gap fe=
lt by
>>>> C++ users to the degree that there=E2=80=99s some half-dozen popular a=
nd
>>>> high-quality implementations available under the name =E2=80=9Cunique_=
function=E2=80=9D.
>>>> [2][3][4][5][6]
>>>>
>>>> C++ has many move-only vocabulary types, and when introduced they
>>>> impose tighter constraints on the interface, and can become =E2=80=9Cv=
iral=E2=80=9D --
>>>> causing any previously copyable paths to require move or forwarding
>>>> operations. Consider
>>>>
>>>> class DbResult {
>>>>
>>>> private:
>>>>
>>>> std::unique_ptr<Blob> data_; // now required!
>>>>
>>>> };
>>>>
>>>> class Reactor {
>>>>
>>>> private:
>>>>
>>>> std::map<std::string, std::function<void()>> reactions_;
>>>>
>>>> };
>>>>
>>>> reactor.on_event(=E2=80=9Cdb-result-ready=E2=80=9D, [&] {
>>>>
>>>> reactor.on_event(=E2=80=9Chas-towel=E2=80=9D, [result =3D std::move(d=
b.result())] {
>>>>
>>>> auto meaning =3D find(result); // 42
>>>>
>>>> });
>>>>
>>>> });
>>>>
>>>> It is not enough to simply std::move the DbResult into the lambda, as
>>>> Reactor::on_event is unable to assign to a move-only lambda as impleme=
nted
>>>> with std::function.
>>>>
>>>> This is a recurring pattern in much concurrent code, such as work
>>>> queues, task graphs, or command buffers. The committee implicitly
>>>> understood the need when it created std::packaged_task, also a type-er=
ased
>>>> polymorphic container, but that type is tightly bound to std::futures,
>>>> which may not be fit for purpose in any code base that doesn=E2=80=99t=
already rely
>>>> on them.
>>>>
>>>> If we are developing any kind of asynchronous work queue we need
>>>>
>>>> 1.
>>>>
>>>> inheritance based polymorphism (and a mechanism to manage heap
>>>> allocated derived objects, such as std::shared_ptr)
>>>> 2.
>>>>
>>>> type-erased container with small object optimization like
>>>> std::function (for copy-only callable types),
>>>> std::packaged_task+std::future (for move-only callable types)
>>>>
>>>>
>>>> However if any facet of our runtime precludes use of std::future --
>>>> such as if it provides its own future type, or does not use futures at=
all,
>>>> we are again left without the ability to use std::unique_ptr or any
>>>> other non-copyable type.
>>>>
>>>> auto unique =3D
>>>>
>>>> std::make_unique<BankTransfer>(=E2=80=9CDrEvil=E2=80=9D, 1000000000);
>>>>
>>>> auto do_bank_transfer =3D
>>>>
>>>> [transfer =3D std::move(unique)] (Bank* to, Bank* from) {
>>>>
>>>> return from->send(transfer, to);
>>>>
>>>> };
>>>>
>>>> ThreadSafeQueue<std::function<int()>> transactions1;
>>>>
>>>> transactions1.emplace(do_bank_transfer); // Compile Error!!
>>>>
>>>> // ...
>>>>
>>>> ThreadSafeQueue<std::packaged_task<int()>> transactions2;
>>>>
>>>> ThreadSafeQueue<int> results
>>>>
>>>> transactions2.emplace(do_bank_transfer);
>>>>
>>>> hpy::async([&] {
>>>>
>>>> while (!transactions2.empty()) {
>>>>
>>>> transactions2.top()();
>>>>
>>>> results.push_back(transactions2.top().get_future()); // ??
>>>>
>>>> }
>>>>
>>>> });
>>>>
>>>> In the above example we simply present wasted human time and
>>>> computational time due to an unnecessary synchronization with std::fut=
ure,
>>>> however a more complex system may indeed need their own future
>>>> implementation which std::packaged_task cannot interoperate with at al=
l.
>>>> Comparison Table
>>>>
>>>> std::promise<Foo> p;
>>>>
>>>> std::unique_ptr<Foo> f;
>>>>
>>>> std::queue<std::function<void()>> a;
>>>>
>>>> std::queue<std::unique_function<void()>> b;
>>>>
>>>> using namespace std;
>>>>
>>>>
>>>> Before Proposal
>>>>
>>>> After Proposal
>>>>
>>>> 1
>>>>
>>>> auto s =3D make_shared<Foo>(move(f));
>>>> a.emplace([s] { s->work(); });
>>>>
>>>>
>>>> // ...
>>>>
>>>> auto shared =3D a.top();
>>>>
>>>> shared();
>>>>
>>>> b.emplace([u =3D move(f)] {
>>>>
>>>> u->work();
>>>>
>>>> });
>>>>
>>>> // ...
>>>>
>>>> auto unique =3D move(b.top());
>>>>
>>>> unique();
>>>>
>>>> 2
>>>>
>>>> a.emplace([r =3D f.get()] {
>>>>
>>>> r->work();
>>>>
>>>> });
>>>>
>>>> b.emplace([u =3D move(f)] {
>>>>
>>>> u->work();
>>>>
>>>> });
>>>>
>>>> 3
>>>>
>>>> atomic<Foo*> result{nullptr};
>>>>
>>>> a.emplace([&result] {
>>>>
>>>> result =3D new Foo;
>>>>
>>>> });
>>>> // ...
>>>> spin_on(result);
>>>> result->work();
>>>>
>>>> auto future =3D p.get_future();
>>>>
>>>> b.emplace([p =3D move(p)] {
>>>>
>>>> p.set_value(Foo{});
>>>>
>>>> });
>>>>
>>>> // ...
>>>>
>>>> future.get().work();
>>>>
>>>> As you can see, attempts to work around the limitation of std::functio=
n
>>>> results in unacceptable undermining of uniqueness semantics, life-time
>>>> safety, and/or ease of use:
>>>>
>>>> 1.
>>>>
>>>> Loss of move-only semantics and extra LoC and a heap allocation per
>>>> shared pointer.
>>>> 2.
>>>>
>>>> Queue lifetime must not exceed enclosing scope lifetime (or
>>>> dangling pointer).
>>>> 3.
>>>>
>>>> Poor usability or unnecessary complexity in search of better
>>>> performance.
>>>>
>>>> Alternatives
>>>>
>>>> Papers =E2=80=9Cstd::function and Beyond=E2=80=9C N4159
>>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf>,
>>>> =E2=80=9CA polymorphic wrapper for all Callable objects (rev. 3)=E2=80=
=9D P0288R1
>>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0288r1.pdf>
>>>> have already argued for fixing std::function to support non-copyable t=
ypes
>>>> (among other issues) some time ago. Yet it seems self evident that as =
long
>>>> and as widely as std::function has been in use, any change that breaks=
the
>>>> observable surface area of std::function is a non-starter. The questio=
n is
>>>> would the use case we outlined herein, if overlaid onto the existing
>>>> std::function, cause previously valid code to break, or conversely
>>>> previously incorrect code to become easily written?
>>>>
>>>> Let=E2=80=99s assume we have a means of =E2=80=9Cfixing=E2=80=9D std::=
function to allow mixing
>>>> of copy and move semantics. Clearly all existing code would continue t=
o
>>>> function as all existing target callable types are CopyConstructible a=
nd
>>>> CopyAssignable, but what if we mix erased instances with copy and move
>>>> semantics? How should the following operations on std::function be def=
ined
>>>> in terms of their target callable types?
>>>>
>>>> Let=E2=80=99s temporarily ignore the details of memory management, and=
consider
>>>> p to be the underlying pointer to the erased instance.
>>>>
>>>> std2::function<void()> c =3D C{}; // Copy-only
>>>> std2::function<void()> m =3D M{}; // Move-only
>>>>
>>>>
>>>> Operation
>>>>
>>>> Definition
>>>>
>>>> Result
>>>>
>>>> c =3D std::move(m);
>>>>
>>>> *((M*)c.p) =3D move(*((M*)m.p));
>>>>
>>>> Move
>>>>
>>>> m =3D std::move(c);
>>>>
>>>> *((C*)c.p) =3D move(*((C*)m.p));
>>>>
>>>> Copy
>>>>
>>>> c =3D m;
>>>>
>>>> *((M*)c.p) =3D *((M*)m.p);
>>>>
>>>> Throw ???
>>>>
>>>> m =3D c;
>>>>
>>>> *((C*)c.p) =3D *((C*)m.p);
>>>>
>>>> Copy
>>>>
>>>> Again we face an unacceptable undermining of uniqueness semantics; in
>>>> addition we have changed the observable surface area of assignment by
>>>> necessitating a new runtime error reporting mechanism for when erased
>>>> targets conflicting behavior, affecting the exception-safety of existi=
ng
>>>> code.
>>>> Shallow v. Deep Const
>>>>
>>>> =E2=80=9CShallow=E2=80=9D or =E2=80=9CDeep=E2=80=9D const in a type er=
ased context means whether the
>>>> constness of the erasing type is extended towards the erased type. For=
our
>>>> discussion we consider whether the the erasing container is const call=
able
>>>> if and only if the underlying type is const callable.
>>>>
>>>>
>>>> It is by now understood that the standard requires const correctness t=
o
>>>> imply thread-safety, and if the container operator() is const, the
>>>> underlying callable type=E2=80=99s operator() must also be const in or=
der to
>>>> hope of satisfying this obligation. So a shallow const container could
>>>> not admit a thread-safe call operation in general, and both N4159
>>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4159.pdf>
>>>> and P0045R1
>>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf>
>>>> draw attention to the unfortunate outcome. The solution presented in t=
hose
>>>> papers it to include the constness of the callable in signature, and t=
o
>>>> have the constness of container operator() be conditional on the signa=
ture.
>>>>
>>>> struct Accessor {
>>>>
>>>> void operator()() const;
>>>>
>>>> // ...
>>>>
>>>> } access;
>>>>
>>>> struct Mutator {
>>>>
>>>> void operator()();
>>>>
>>>> // ...
>>>>
>>>> } mutate;
>>>>
>>>> std3::function<void() const> a =3D access; // ok
>>>>
>>>> std3::function<void()> b =3D access; // ok
>>>>
>>>> std3::function<void()> c =3D mutate; // ok
>>>>
>>>> std3::function<void() const> d =3D mutate; // compile error
>>>>
>>>> a =3D b; // compile error: target type more restrictive
>>>>
>>>> b =3D a; // ok
>>>>
>>>> b =3D c; // ok
>>>>
>>>>
>>>> This proposal, while in the author=E2=80=99s opinion is highly recomme=
nded
>>>> improvement, it=E2=80=99s best presented in referenced papers, and for=
simplicity=E2=80=99s
>>>> sake isn=E2=80=99t pursued further here.
>>>>
>>>> Otherwise, without the above but desiring deep const semantics, we
>>>> would wish that const containers require const callable targets. Howev=
er,
>>>> since we have erase the constness of target instance, we are left with
>>>> throwing when deep const is violated, breaking existing exception-safe=
code.
>>>>
>>>> const std4::function<void()> a; // deep const
>>>>
>>>> std::function<void()> b =3D mutate; // non-const target
>>>>
>>>> a =3D b; // target copied
>>>>
>>>> a(); // now throws!
>>>> Necessity and Cost
>>>>
>>>> We can all agree type erased containers should support as much as
>>>> feasible the const correctness of its target types, but we began our
>>>> argument with a specific asynchronous use case that involved deferred
>>>> computations, often invoked on foreign threads. If this pattern as see=
n =E2=80=9Cin
>>>> the wild=E2=80=9D makes use of thread safe queues, is thread safety of=
the
>>>> container itself actually sufficient to justify the costs associated w=
ith
>>>> extra synchronization or exception safety? Even if we can guarantee co=
nst
>>>> container only calls const target methods, we still cannot guarantee t=
he
>>>> target itself makes the connection between const and thread safety.
>>>>
>>>> Should a proposed std::unique_function emulate =E2=80=9Cbroken=E2=80=
=9D shallow const
>>>> correctness of std::function for uniformity, or is =E2=80=9Cfixing=E2=
=80=9D the
>>>> contradiction worth breaking runtime changes? And is std::unique_/func=
tion
>>>> more like a container or pointer (where const is understood to be shal=
low),
>>>> or is it more like an opaque type (where const is generally considered=
to
>>>> be deep)? Historically we allow container const to vary independently =
of
>>>> parameterized types when they exist, suggesting std::function should r=
emain
>>>> a shallow container.
>>>>
>>>> While this question is relevant to the specification of
>>>> std::unique_function, it is ultimately orthogonal to the question of
>>>> the need for std::unique_function to exist, which is this paper=E2=80=
=99s main
>>>> concern.
>>>> Conclusion
>>>>
>>>> So long as we have move-only lambdas and type erased callable
>>>> containers, a move-only capable std::function is required. As uniquene=
ss
>>>> semantics of container are orthogonal to const-correctness of the inte=
rface
>>>> we recommend not conflating the two, and pursuing P0045R1
>>>> <http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf>
>>>> for const-correctness as an independent feature request.
>>>> References
>>>>
>>>> [1] https://reviews.llvm.org/D48349
>>>>
>>>> [2] http://llvm.org/doxygen/FunctionExtras_8h_source.html#l00046
>>>>
>>>> [3]
>>>> https://github.com/STEllAR-GROUP/hpx/blob/master/hpx/util/unique_funct=
ion.hpp
>>>>
>>>> [4]
>>>> https://github.com/potswa/cxx_function/blob/master/cxx_function.hpp#L1=
192
>>>>
>>>> [5]
>>>> https://github.com/Naios/function2/blob/master/include/function2/funct=
ion2.hpp#L1406
>>>>
>>>> [6] https://github.com/facebook/folly/blob/master/folly/Function.h
>>>>
>>>> --
>>>> 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/CAHn%2BA5=
NyaUQjAeudtObjn08Trz4iJ%2Bu-GGt2J5VnmtmZJiPVxg%40mail.gmail.com
>>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHn%2BA=
5NyaUQjAeudtObjn08Trz4iJ%2Bu-GGt2J5VnmtmZJiPVxg%40mail.gmail.com?utm_medium=
=3Demail&utm_source=3Dfooter>
>>>> .
>>>>
>>> --
>>> 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/CAJH_FNW1P=
Vw2BeYJCWfKNKN3_67eLY_6wG1vgNJOZx9oQS%2Bs%3DQ%40mail.gmail.com
>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJH_FNW1=
PVw2BeYJCWfKNKN3_67eLY_6wG1vgNJOZx9oQS%2Bs%3DQ%40mail.gmail.com?utm_medium=
=3Demail&utm_source=3Dfooter>
>>> .
>>>
>> --
>> You received this message because you are subscribed to the Google Group=
s
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> 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/CAHn%2BA5NH=
iEO1rTKfZOryWnW-NTqLGgim6epp-Bt03iU5wd-EEA%40mail.gmail.com
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHn%2BA5N=
HiEO1rTKfZOryWnW-NTqLGgim6epp-Bt03iU5wd-EEA%40mail.gmail.com?utm_medium=3De=
mail&utm_source=3Dfooter>
>> .
>>
> --
> 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/CAJH_FNWs-rP=
4hc6V3pE1vTgQgtTUKfNsJOmOzsxWvwRzsC2ywA%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJH_FNWs-r=
P4hc6V3pE1vTgQgtTUKfNsJOmOzsxWvwRzsC2ywA%40mail.gmail.com?utm_medium=3Demai=
l&utm_source=3Dfooter>
> .
>
--=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/CAHn%2BA5PiWBuc33MR6Sr%2BvU4W%3DWtcENvMc4Nf%2BYP=
-8joBNPnYQw%40mail.gmail.com.
--000000000000b52ed10578e7e979
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I reference P0045, but my paper is independent. Essentiall=
y "we need this, it's kind of obvious, let's decide if it'=
s like std::function or "fixed" by P0045".<br><br>If you or =
your team will be at SD we can bang out some wording in an hour I feel.</di=
v><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Tue, Oct 23, 2018 at 9=
:26 AM Lee Howes <<a href=3D"mailto:xrikcus@gmail.com">xrikcus@gmail.com=
</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:=
0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Fr=
om the minutes from the presentation of P0288 in Toronto it looks like ther=
e was a request for updated wording to make it independent of P0045, but ot=
herwise little obvious concern. It seems likely that that's the importa=
nt change to make.<div><br></div><div>Given the paper reading load between =
now and SD we're going to be overwhelmed, I think. I'd be happy to =
give some feedback on a wording draft in the short term.</div></div><br><di=
v class=3D"gmail_quote"><div dir=3D"ltr">On Tue, 23 Oct 2018 at 09:18, Ryan=
McDougall <<a href=3D"mailto:mcdougall.ryan@gmail.com" target=3D"_blank=
">mcdougall.ryan@gmail.com</a>> wrote:<br></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div dir=3D"ltr">Yes, I'll be at SD in order to push this paper =
-- thought I don't know if there's room on anyone schedule. I have =
hope however since it's relatively uncontroversial it can yet be fast t=
racked. I would very much like help with wording if you're available.<d=
iv><br></div><div>Cheers,</div></div><br><div class=3D"gmail_quote"><div di=
r=3D"ltr">On Tue, Oct 23, 2018 at 9:14 AM Lee Howes <<a href=3D"mailto:x=
rikcus@gmail.com" target=3D"_blank">xrikcus@gmail.com</a>> wrote:<br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr">Hi Ryan,<div>Are you pla=
nning to attend the meeting and argue the case for unique_function? This is=
something that came up again this week for us at Facebook as well, and whi=
le we work around it with folly::Function as you noted, having to do so is =
not optimal. It would certainly be a good thing to get a unique_function in=
to the standard soonish.</div><div><br></div><div>Lee Howes</div></div><br>=
<div class=3D"gmail_quote"><div dir=3D"ltr">On Mon, 22 Oct 2018 at 11:19, R=
yan McDougall <<a href=3D"mailto:mcdougall.ryan@gmail.com" target=3D"_bl=
ank">mcdougall.ryan@gmail.com</a>> wrote:<br></div><blockquote class=3D"=
gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"ltr"><span id=3D"m_-5373236172660489361m_-29956014666=
36599522m_-1335907127606806884m_-3924309839588613576gmail-docs-internal-gui=
d-def7cea7-7fff-bf6e-c2f3-4764896f986c"><p dir=3D"ltr" style=3D"line-height=
:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-=
family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap">=E2=80=9CThis is motivated by increasing usage of things like=
executors and the task</span></p><p dir=3D"ltr" style=3D"line-height:1.38;=
margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family=
:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pr=
e-wrap">queue where it is useful to embed move-only types like a std::promi=
se within</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt=
;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:r=
gb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-var=
iant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">a type=
erased function. That isn't possible without this version of a type</s=
pan></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bott=
om:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);ba=
ckground-color:transparent;font-variant-numeric:normal;font-variant-east-as=
ian:normal;vertical-align:baseline;white-space:pre-wrap">erased function.=
=E2=80=9D -- Chandler Carruth[1]</span></p><h1 dir=3D"ltr" style=3D"line-he=
ight:1.38;margin-top:20pt;margin-bottom:6pt"><span style=3D"font-size:20pt;=
font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-weight=
:400;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-al=
ign:baseline;white-space:pre-wrap">Thanks</span></h1><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">=E2=80=9Cstd::function and Beyond=E2=80=9C </s=
pan><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n415=
9.pdf" style=3D"text-decoration-line:none" target=3D"_blank"><span style=3D=
"font-size:11pt;font-family:Arial;background-color:transparent;font-variant=
-numeric:normal;font-variant-east-asian:normal;text-decoration-line:underli=
ne;vertical-align:baseline;white-space:pre-wrap">N4159</span></a><span styl=
e=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tra=
nsparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertica=
l-align:baseline;white-space:pre-wrap">, =E2=80=9CQualified std::function S=
ignatures=E2=80=9D </span><a href=3D"http://www.open-std.org/jtc1/sc22/wg21=
/docs/papers/2017/p0045r1.pdf" style=3D"text-decoration-line:none" target=
=3D"_blank"><span style=3D"font-size:11pt;font-family:Arial;background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;te=
xt-decoration-line:underline;vertical-align:baseline;white-space:pre-wrap">=
P0045R1</span></a><span style=3D"font-size:11pt;font-family:Arial;color:rgb=
(0,0,0);background-color:transparent;font-variant-numeric:normal;font-varia=
nt-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">, and =
=E2=80=9CA polymorphic wrapper for all Callable objects (rev. 3)=E2=80=9D <=
/span><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0=
288r1.pdf" style=3D"text-decoration-line:none" target=3D"_blank"><span styl=
e=3D"font-size:11pt;font-family:Arial;background-color:transparent;font-var=
iant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:und=
erline;vertical-align:baseline;white-space:pre-wrap">P0288R1</span></a><spa=
n style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-col=
or:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;v=
ertical-align:baseline;white-space:pre-wrap"> et al. for laying the groundw=
ork for this paper. Thank you to David Krauss and Arthur O=E2=80=99Dwyer fo=
r your discussion and feedback. Thank you all authors of alternative type e=
rased callable containers for your proof and inspiration.</span></p><h1 dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:20pt;margin-bottom:6pt"><span=
style=3D"font-size:20pt;font-family:Arial;color:rgb(0,0,0);background-colo=
r:transparent;font-weight:400;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap">Motivation</spa=
n></h1><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-botto=
m:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap">std::function model=
s both CopyConstructible and CopyAssignable, and requires its erased target=
type to declare a copy constructor. This means std::function =C2=A0is hope=
lessly incompatible with std::unique_ptr, std::promise, or any other move-o=
nly type. This is a functional gap felt by C++ users to the degree that the=
re=E2=80=99s some half-dozen popular and high-quality implementations avail=
able under the name =E2=80=9Cunique_function=E2=80=9D. [2][3][4][5][6]</spa=
n></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bo=
ttom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);=
background-color:transparent;font-variant-numeric:normal;font-variant-east-=
asian:normal;vertical-align:baseline;white-space:pre-wrap">C++ has many mov=
e-only vocabulary types, and when introduced they impose tighter constraint=
s on the interface, and can become =E2=80=9Cviral=E2=80=9D -- causing any p=
reviously copyable paths to require move or forwarding operations. Consider=
</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;marg=
in-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&=
quot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre=
-wrap">class DbResult {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;=
margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family=
:"Courier New";color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap"> private:</span></p><p dir=3D"ltr" style=3D"line-=
height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt=
;font-family:"Courier New";color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap"> =C2=A0std::unique_ptr<Blob> da=
ta_; =C2=A0// now required!</span></p><p dir=3D"ltr" style=3D"line-height:1=
..38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-fa=
mily:"Courier New";color:rgb(0,0,0);background-color:transparent;=
font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:b=
aseline;white-space:pre-wrap">};</span></p><br><p dir=3D"ltr" style=3D"line=
-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11p=
t;font-family:"Courier New";color:rgb(0,0,0);background-color:tra=
nsparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertica=
l-align:baseline;white-space:pre-wrap">class Reactor {</span></p><p dir=3D"=
ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span styl=
e=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);ba=
ckground-color:transparent;font-variant-numeric:normal;font-variant-east-as=
ian:normal;vertical-align:baseline;white-space:pre-wrap"> private:</span></=
p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt=
"><span style=3D"font-size:11pt;font-family:"Courier New";color:r=
gb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-var=
iant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=
=A0std::map<std::string, std::function<void()>> reactions_;</sp=
an></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-botto=
m:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";co=
lor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fon=
t-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">}=
;</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;mar=
gin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New=
";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pr=
e-wrap">reactor.on_event(=E2=80=9Cdb-result-ready=E2=80=9D, [&] {</span=
></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:=
0pt"><span style=3D"font-size:11pt;font-family:"Courier New";colo=
r:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-=
variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =
=C2=A0reactor.on_event(=E2=80=9Chas-towel=E2=80=9D, [result =3D std::move(d=
b.result())] {</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-to=
p:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Co=
urier New";color:rgb(0,0,0);background-color:transparent;font-variant-=
numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white=
-space:pre-wrap"> =C2=A0=C2=A0=C2=A0auto meaning =3D find(result); // 42</s=
pan></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bott=
om:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";c=
olor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fo=
nt-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">=
=C2=A0});</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0p=
t;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courie=
r New";color:rgb(0,0,0);background-color:transparent;font-variant-nume=
ric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spa=
ce:pre-wrap">});</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;mar=
gin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Ar=
ial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norm=
al;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-w=
rap">It is not enough to simply std::move the DbResult into the lambda, as =
Reactor::on_event is unable to assign to a move-only lambda as implemented =
with std::function.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;=
margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family=
:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pr=
e-wrap">This is a recurring pattern in much concurrent code, such as work q=
ueues, task graphs, or command buffers. The committee implicitly understood=
the need when it created std::packaged_task, also a type-erased polymorphi=
c container, but that type is tightly bound to std::futures, which may not =
be fit for purpose in any code base that doesn=E2=80=99t already rely on th=
em.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;m=
argin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb=
(0,0,0);background-color:transparent;font-variant-numeric:normal;font-varia=
nt-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">If we ar=
e developing</span><span style=3D"font-size:11pt;font-family:Arial;color:rg=
b(0,0,0);background-color:transparent;font-style:italic;font-variant-numeri=
c:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space=
:pre-wrap"> any</span><span style=3D"font-size:11pt;font-family:Arial;color=
:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> kin=
d of asynchronous work queue we need </span></p><ol style=3D"margin-top:0pt=
;margin-bottom:0pt"><li dir=3D"ltr" style=3D"list-style-type:upper-alpha;fo=
nt-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap"><p dir=3D"ltr" style=3D"line-height:1.38;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;background-co=
lor:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;=
vertical-align:baseline;white-space:pre-wrap">inheritance based polymorphis=
m (and a mechanism to manage heap allocated derived objects, such as std::s=
hared_ptr)</span></p></li><li dir=3D"ltr" style=3D"list-style-type:upper-al=
pha;font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap"><p dir=3D"ltr" style=3D"line-height:1=
..38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;backgro=
und-color:transparent;font-variant-numeric:normal;font-variant-east-asian:n=
ormal;vertical-align:baseline;white-space:pre-wrap">type-erased container w=
ith </span><span style=3D"font-size:11pt;background-color:transparent;font-=
style:italic;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap">small object optimization</span>=
<span style=3D"font-size:11pt;background-color:transparent;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap"> like std::function (for copy-only callable types), std::pack=
aged_task+std::future (for move-only callable types)</span></p></li></ol><b=
r><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt=
"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap">However if any facet of =
our runtime precludes use of std::future -- such as if it provides its own =
future type, or does not use futures at all, we are again left without the =
ability to use std::unique_ptr or </span><span style=3D"font-size:11pt;font=
-family:Arial;color:rgb(0,0,0);background-color:transparent;font-weight:700=
;font-style:italic;font-variant-numeric:normal;font-variant-east-asian:norm=
al;vertical-align:baseline;white-space:pre-wrap">any other</span><span styl=
e=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tra=
nsparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertica=
l-align:baseline;white-space:pre-wrap"> non-copyable type.</span></p><br><p=
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">auto uniqu=
e =3D</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;mar=
gin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New=
";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pr=
e-wrap"> =C2=A0std::make_unique<BankTransfer>(=E2=80=9CDrEvil=E2=80=
=9D, 1000000000);</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&=
quot;Courier New";color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">auto do_bank_transfer =3D</span></p><p dir=3D"ltr" =
style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"=
font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgro=
und-color:transparent;font-variant-numeric:normal;font-variant-east-asian:n=
ormal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0[transfer =3D st=
d::move(unique)] (Bank* to, Bank* from) {</span></p><p dir=3D"ltr" style=3D=
"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-siz=
e:11pt;font-family:"Courier New";color:rgb(0,0,0);background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ve=
rtical-align:baseline;white-space:pre-wrap"> =C2=A0=C2=A0=C2=A0return from-=
>send(transfer, to);</span></p><p dir=3D"ltr" style=3D"line-height:1.38;=
margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family=
:"Courier New";color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap">};</span></p><br><p dir=3D"ltr" style=3D"line-hei=
ght:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;fo=
nt-family:"Courier New";color:rgb(0,0,0);background-color:transpa=
rent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-al=
ign:baseline;white-space:pre-wrap">ThreadSafeQueue<std::function<int(=
)>> transactions1;</span></p><p dir=3D"ltr" style=3D"line-height:1.38=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-famil=
y:"Courier New";color:rgb(0,0,0);background-color:transparent;fon=
t-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:base=
line;white-space:pre-wrap">transactions1.emplace(do_bank_transfer); =C2=A0/=
/ Compile Error!!</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&=
quot;Courier New";color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">// ...</span></p><br><p dir=3D"ltr" style=3D"line-h=
eight:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;=
font-family:"Courier New";color:rgb(0,0,0);background-color:trans=
parent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-=
align:baseline;white-space:pre-wrap">ThreadSafeQueue<std::packaged_task&=
lt;int()>> transactions2;</span></p><p dir=3D"ltr" style=3D"line-heig=
ht:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;fon=
t-family:"Courier New";color:rgb(0,0,0);background-color:transpar=
ent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-ali=
gn:baseline;white-space:pre-wrap">ThreadSafeQueue<int> results</span>=
</p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0=
pt"><span style=3D"font-size:11pt;font-family:"Courier New";color=
:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">tran=
sactions2.emplace(do_bank_transfer);</span></p><br><p dir=3D"ltr" style=3D"=
line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size=
:11pt;font-family:"Courier New";color:rgb(0,0,0);background-color=
:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap">hpy::async([&] {</span></p><=
p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><=
span style=3D"font-size:11pt;font-family:"Courier New";color:rgb(=
0,0,0);background-color:transparent;font-variant-numeric:normal;font-varian=
t-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0wh=
ile (!transactions2.empty()) {</span></p><p dir=3D"ltr" style=3D"line-heigh=
t:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font=
-family:"Courier New";color:rgb(0,0,0);background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap"> =C2=A0=C2=A0=C2=A0transactions2.top()();<=
/span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bo=
ttom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New"=
;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;=
font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap=
"> =C2=A0=C2=A0=C2=A0results.push_back(transactions2.top().get_future()); /=
/ ??</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;marg=
in-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&=
quot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre=
-wrap"> =C2=A0}</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-t=
op:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"C=
ourier New";color:rgb(0,0,0);background-color:transparent;font-variant=
-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whit=
e-space:pre-wrap">});</span></p><br><p dir=3D"ltr" style=3D"line-height:1.3=
8;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-fami=
ly:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric=
:normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:=
pre-wrap">In the above example we simply present wasted human time and comp=
utational time due to an unnecessary synchronization with std::future, howe=
ver a more complex system may indeed need their own future implementation w=
hich std::packaged_task cannot interoperate with at all.</span></p><h1 dir=
=3D"ltr" style=3D"line-height:1.38;margin-top:20pt;margin-bottom:6pt"><span=
style=3D"font-size:20pt;font-family:Arial;color:rgb(0,0,0);background-colo=
r:transparent;font-weight:400;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap">Comparison Tabl=
e</span></h1><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin=
-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New&qu=
ot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norm=
al;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-w=
rap">std::promise<Foo> p;</span></p><p dir=3D"ltr" style=3D"line-heig=
ht:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;fon=
t-family:"Courier New";color:rgb(0,0,0);background-color:transpar=
ent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-ali=
gn:baseline;white-space:pre-wrap">std::unique_ptr<Foo> f;</span></p><=
p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:10pt;font-family:"Courier New";color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">std::queue=
<std::function<void()>> a;</span></p><p dir=3D"ltr" style=3D"li=
ne-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10=
pt;font-family:"Courier New";color:rgb(0,0,0);background-color:tr=
ansparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertic=
al-align:baseline;white-space:pre-wrap">std::queue<std::unique_function&=
lt;void()>> b;</span></p><p dir=3D"ltr" style=3D"line-height:1.38;mar=
gin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:&q=
uot;Courier New";color:rgb(0,0,0);background-color:transparent;font-va=
riant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline=
;white-space:pre-wrap">using namespace std;</span></p><br><div dir=3D"ltr" =
style=3D"margin-left:0pt"><table style=3D"border:none;border-collapse:colla=
pse"><colgroup><col width=3D"17"><col width=3D"295"><col width=3D"289"></co=
lgroup><tbody><tr style=3D"height:0pt"><td style=3D"border-width:1pt;border=
-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><br></=
td><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0)=
;vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:A=
rial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:nor=
mal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-=
wrap">Before Proposal</span></p></td><td style=3D"border-width:1pt;border-s=
tyle:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=
=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span s=
tyle=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:=
transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vert=
ical-align:baseline;white-space:pre-wrap">After Proposal</span></p></td></t=
r><tr style=3D"height:67pt"><td style=3D"border-width:1pt;border-style:soli=
d;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" st=
yle=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"fon=
t-size:10pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent=
;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:=
baseline;white-space:pre-wrap">1</span></p></td><td style=3D"border-width:1=
pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5p=
t"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt=
"><span style=3D"font-size:10pt;font-family:"Courier New";color:r=
gb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-var=
iant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">auto s=
=3D make_shared<Foo>(move(f));</span><span style=3D"font-size:10pt;f=
ont-family:"Courier New";color:rgb(0,0,0);background-color:transp=
arent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-a=
lign:baseline;white-space:pre-wrap"><br class=3D"m_-5373236172660489361m_-2=
995601466636599522m_-1335907127606806884m_-3924309839588613576gmail-kix-lin=
e-break"></span><span style=3D"font-size:10pt;font-family:"Courier New=
";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pr=
e-wrap">a.emplace([s] { s->work(); });</span></p><p dir=3D"ltr" style=3D=
"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size=
:10pt;font-family:"Courier New";color:rgb(0,0,0);background-color=
:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap"><br class=3D"m_-5373236172660489=
361m_-2995601466636599522m_-1335907127606806884m_-3924309839588613576gmail-=
kix-line-break"></span><span style=3D"font-size:10pt;font-family:"Cour=
ier New";color:rgb(0,0,0);background-color:transparent;font-variant-nu=
meric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-s=
pace:pre-wrap">// ...</span></p><p dir=3D"ltr" style=3D"line-height:1.2;mar=
gin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:&q=
uot;Courier New";color:rgb(0,0,0);background-color:transparent;font-va=
riant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline=
;white-space:pre-wrap">auto shared =3D a.top();</span></p><p dir=3D"ltr" st=
yle=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"fon=
t-size:10pt;font-family:"Courier New";color:rgb(0,0,0);background=
-color:transparent;font-variant-numeric:normal;font-variant-east-asian:norm=
al;vertical-align:baseline;white-space:pre-wrap">shared();</span></p></td><=
td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);ver=
tical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin=
-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"=
;Courier New";color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap">b.emplace([u =3D move(f)] {</span></p><p dir=3D"ltr" st=
yle=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"fon=
t-size:10pt;font-family:"Courier New";color:rgb(0,0,0);background=
-color:transparent;font-variant-numeric:normal;font-variant-east-asian:norm=
al;vertical-align:baseline;white-space:pre-wrap"> =C2=A0u->work();</span=
></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0=
pt"><span style=3D"font-size:10pt;font-family:"Courier New";color=
:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">});<=
/span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bot=
tom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New";=
color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;f=
ont-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"=
>// ...</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;ma=
rgin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier Ne=
w";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap">auto unique =3D move(b.top());</span></p><p dir=3D"ltr" style=3D"l=
ine-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
0pt;font-family:"Courier New";color:rgb(0,0,0);background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;verti=
cal-align:baseline;white-space:pre-wrap">unique();</span></p></td></tr><tr =
style=3D"height:0pt"><td style=3D"border-width:1pt;border-style:solid;borde=
r-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"=
line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:=
10pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">2</span></p></td><td style=3D"border-width:1pt;bord=
er-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p d=
ir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span=
style=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,=
0);background-color:transparent;font-variant-numeric:normal;font-variant-ea=
st-asian:normal;vertical-align:baseline;white-space:pre-wrap">a.emplace([r =
=3D f.get()] {</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top=
:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Cou=
rier New";color:rgb(0,0,0);background-color:transparent;font-variant-n=
umeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-=
space:pre-wrap"> =C2=A0r->work();</span></p><p dir=3D"ltr" style=3D"line=
-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt=
;font-family:"Courier New";color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap">});</span></p></td><td style=3D"borde=
r-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;p=
adding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-b=
ottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New"=
;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal=
;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wra=
p">b.emplace([u =3D move(f)] {</span></p><p dir=3D"ltr" style=3D"line-heigh=
t:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-=
family:"Courier New";color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap"> =C2=A0u->work();</span></p><p dir=3D"lt=
r" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap">});</span></p></td>=
</tr><tr style=3D"height:0pt"><td style=3D"border-width:1pt;border-style:so=
lid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" =
style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"f=
ont-size:10pt;font-family:Arial;color:rgb(0,0,0);background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap">3</span></p></td><td style=3D"border-width=
:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;padding:=
5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0=
pt"><span style=3D"font-size:10pt;font-family:"Courier New";color=
:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">atom=
ic<Foo*> result{nullptr};</span></p><p dir=3D"ltr" style=3D"line-heig=
ht:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font=
-family:"Courier New";color:rgb(0,0,0);background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap">a.emplace([&result] {</span></p><p dir=
=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span s=
tyle=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0)=
;background-color:transparent;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0result =
=3D new Foo;</span></p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0=
pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Couri=
er New";color:rgb(0,0,0);background-color:transparent;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap">});</span><span style=3D"font-size:10pt;font-family:"Cou=
rier New";color:rgb(0,0,0);background-color:transparent;font-variant-n=
umeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-=
space:pre-wrap"><br class=3D"m_-5373236172660489361m_-2995601466636599522m_=
-1335907127606806884m_-3924309839588613576gmail-kix-line-break"></span><spa=
n style=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0=
,0);background-color:transparent;font-variant-numeric:normal;font-variant-e=
ast-asian:normal;vertical-align:baseline;white-space:pre-wrap">// ...</span=
><span style=3D"font-size:10pt;font-family:"Courier New";color:rg=
b(0,0,0);background-color:transparent;font-variant-numeric:normal;font-vari=
ant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br cla=
ss=3D"m_-5373236172660489361m_-2995601466636599522m_-1335907127606806884m_-=
3924309839588613576gmail-kix-line-break"></span><span style=3D"font-size:10=
pt;font-family:"Courier New";color:rgb(0,0,0);background-color:tr=
ansparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertic=
al-align:baseline;white-space:pre-wrap">spin_on(result);</span><span style=
=3D"font-size:10pt;font-family:"Courier New";color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap"><br class=3D"m_-537=
3236172660489361m_-2995601466636599522m_-1335907127606806884m_-392430983958=
8613576gmail-kix-line-break"></span><span style=3D"font-size:10pt;font-fami=
ly:"Courier New";color:rgb(0,0,0);background-color:transparent;fo=
nt-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:bas=
eline;white-space:pre-wrap">result->work();</span></p></td><td style=3D"=
border-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:=
top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;mar=
gin-bottom:0pt"><span style=3D"font-size:10pt;font-family:"Courier New=
";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:n=
ormal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pr=
e-wrap">auto future =3D p.get_future();</span></p><p dir=3D"ltr" style=3D"l=
ine-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
0pt;font-family:"Courier New";color:rgb(0,0,0);background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;verti=
cal-align:baseline;white-space:pre-wrap">b.emplace([p =3D move(p)] {</span>=
</p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0p=
t"><span style=3D"font-size:10pt;font-family:"Courier New";color:=
rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> =C2=
=A0p.set_value(Foo{});</span></p><p dir=3D"ltr" style=3D"line-height:1.2;ma=
rgin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-family:&=
quot;Courier New";color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">});</span></p><p dir=3D"ltr" style=3D"line-height:1=
..2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;font-fam=
ily:"Courier New";color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">// ...</span></p><p dir=3D"ltr" style=3D"line-=
height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:10pt;=
font-family:"Courier New";color:rgb(0,0,0);background-color:trans=
parent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-=
align:baseline;white-space:pre-wrap">future.get().work();</span></p></td></=
tr></tbody></table></div><br><p dir=3D"ltr" style=3D"line-height:1.38;margi=
n-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Aria=
l;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal=
;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wra=
p">As you can see, attempts to work around the limitation of std::function =
results in unacceptable undermining of uniqueness semantics, life-time safe=
ty, and/or ease of use:</span></p><ol style=3D"margin-top:0pt;margin-bottom=
:0pt"><li dir=3D"ltr" style=3D"list-style-type:decimal;font-size:11pt;font-=
family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-num=
eric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-sp=
ace:pre-wrap"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margi=
n-bottom:0pt"><span style=3D"font-size:11pt;background-color:transparent;fo=
nt-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:bas=
eline;white-space:pre-wrap">Loss of move-only semantics and extra LoC and a=
heap allocation per shared pointer.</span></p></li><li dir=3D"ltr" style=
=3D"list-style-type:decimal;font-size:11pt;font-family:Arial;color:rgb(0,0,=
0);background-color:transparent;font-variant-numeric:normal;font-variant-ea=
st-asian:normal;vertical-align:baseline;white-space:pre-wrap"><p dir=3D"ltr=
" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:11pt;background-color:transparent;font-variant-numeric:normal=
;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wra=
p">Queue lifetime must not exceed enclosing scope lifetime (or dangling poi=
nter).</span></p></li><li dir=3D"ltr" style=3D"list-style-type:decimal;font=
-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;=
font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:b=
aseline;white-space:pre-wrap"><p dir=3D"ltr" style=3D"line-height:1.38;marg=
in-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ve=
rtical-align:baseline;white-space:pre-wrap">Poor usability or unnecessary c=
omplexity in search of better performance.</span></p></li></ol><h1 dir=3D"l=
tr" style=3D"line-height:1.38;margin-top:20pt;margin-bottom:6pt"><span styl=
e=3D"font-size:20pt;font-family:Arial;color:rgb(0,0,0);background-color:tra=
nsparent;font-weight:400;font-variant-numeric:normal;font-variant-east-asia=
n:normal;vertical-align:baseline;white-space:pre-wrap">Alternatives</span><=
/h1><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0=
pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgr=
ound-color:transparent;font-variant-numeric:normal;font-variant-east-asian:=
normal;vertical-align:baseline;white-space:pre-wrap">Papers =E2=80=9Cstd::f=
unction and Beyond=E2=80=9C </span><a href=3D"http://www.open-std.org/jtc1/=
sc22/wg21/docs/papers/2014/n4159.pdf" style=3D"text-decoration-line:none" t=
arget=3D"_blank"><span style=3D"font-size:11pt;font-family:Arial;background=
-color:transparent;font-variant-numeric:normal;font-variant-east-asian:norm=
al;text-decoration-line:underline;vertical-align:baseline;white-space:pre-w=
rap">N4159</span></a><span style=3D"font-size:11pt;font-family:Arial;color:=
rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">, =E2=
=80=9CA polymorphic wrapper for all Callable objects (rev. 3)=E2=80=9D </sp=
an><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0288=
r1.pdf" style=3D"text-decoration-line:none" target=3D"_blank"><span style=
=3D"font-size:11pt;font-family:Arial;background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:unde=
rline;vertical-align:baseline;white-space:pre-wrap">P0288R1</span></a><span=
style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ve=
rtical-align:baseline;white-space:pre-wrap"> have already argued for fixing=
std::function to support non-copyable types (among other issues) some time=
ago. Yet it seems self evident that as long and as widely as std::function=
has been in use, any change that breaks the observable surface area of std=
::function is a non-starter. The question is would the use case we outlined=
herein, if overlaid onto the existing std::function, cause previously vali=
d code to break, or conversely previously incorrect code to become easily w=
ritten?</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0=
pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color=
:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-v=
ariant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Let=
=E2=80=99s assume we have a means of =E2=80=9Cfixing=E2=80=9D std::function=
to allow mixing of copy and move semantics. Clearly all existing code woul=
d continue to function as all existing target callable types are CopyConstr=
uctible and CopyAssignable, but what if we mix erased instances with copy a=
nd move semantics? How should the following operations on std::function be =
defined in terms of their target callable types?</span></p><br><p dir=3D"lt=
r" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap">Let=E2=80=99s temporarily ignore the =
details of memory management, and consider </span><span style=3D"font-size:=
11pt;font-family:"Courier New";color:rgb(0,0,0);background-color:=
transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vert=
ical-align:baseline;white-space:pre-wrap">p</span><span style=3D"font-size:=
11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap"> to be the underlying pointer to the erased instanc=
e.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;ma=
rgin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier Ne=
w";color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap">std2::function<void()> c =3D C{}; // Copy-only</span><span s=
tyle=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0)=
;background-color:transparent;font-variant-numeric:normal;font-variant-east=
-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br class=3D"m_=
-5373236172660489361m_-2995601466636599522m_-1335907127606806884m_-39243098=
39588613576gmail-kix-line-break"></span><span style=3D"font-size:11pt;font-=
family:"Courier New";color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap">std2::function<void()> m =3D M{}; // =
Move-only</span></p><br><br><div dir=3D"ltr" style=3D"margin-left:0pt"><tab=
le style=3D"border:none;border-collapse:collapse"><colgroup><col width=3D"1=
63"><col width=3D"276"><col width=3D"166"></colgroup><tbody><tr style=3D"he=
ight:0pt"><td style=3D"border-width:1pt;border-style:solid;border-color:rgb=
(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height=
:1.38;margin-top:0pt;margin-bottom:0pt;text-align:center"><span style=3D"fo=
nt-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap">Operation</span></p></td><td style=3D"borde=
r-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;p=
adding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt;text-align:center"><span style=3D"font-size:11pt;font-family:Ari=
al;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">Definition</span></p></td><td style=3D"border-width:1pt;border-style:so=
lid;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" =
style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt;text-align:cente=
r"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgro=
und-color:transparent;font-variant-numeric:normal;font-variant-east-asian:n=
ormal;vertical-align:baseline;white-space:pre-wrap">Result</span></p></td><=
/tr><tr style=3D"height:0pt"><td style=3D"border-width:1pt;border-style:sol=
id;border-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" s=
tyle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"f=
ont-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap">c =3D std::move(m);</spa=
n></p></td><td style=3D"border-width:1pt;border-style:solid;border-color:rg=
b(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-heigh=
t:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font=
-family:"Courier New";color:rgb(0,0,0);background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap">*((M*)c.p) =3D move(*((M*)m.p));</span></p=
></td><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0=
,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.3=
8;margin-top:0pt;margin-bottom:0pt;text-align:center"><span style=3D"font-s=
ize:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;fo=
nt-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:bas=
eline;white-space:pre-wrap">Move</span></p></td></tr><tr style=3D"height:0p=
t"><td style=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0)=
;vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;m=
argin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:=
"Courier New";color:rgb(0,0,0);background-color:transparent;font-=
variant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseli=
ne;white-space:pre-wrap">m =3D std::move(c);</span></p></td><td style=3D"bo=
rder-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:to=
p;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;marg=
in-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&=
quot;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre=
-wrap">*((C*)c.p) =3D move(*((C*)m.p));</span></p></td><td style=3D"border-=
width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;pad=
ding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bo=
ttom:0pt;text-align:center"><span style=3D"font-size:11pt;font-family:Arial=
;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;=
font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap=
">Copy</span></p></td></tr><tr style=3D"height:0pt"><td style=3D"border-wid=
th:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;paddin=
g:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-botto=
m:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";co=
lor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fon=
t-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">c=
=3D m;</span></p></td><td style=3D"border-width:1pt;border-style:solid;bor=
der-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:"Courier New";color:rgb(153,153,153);backgr=
ound-color:transparent;font-variant-numeric:normal;font-variant-east-asian:=
normal;vertical-align:baseline;white-space:pre-wrap">*((M*)c.p) =3D *((M*)m=
..p);</span></p></td><td style=3D"border-width:1pt;border-style:solid;border=
-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D"l=
ine-height:1.38;margin-top:0pt;margin-bottom:0pt;text-align:center"><span s=
tyle=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:=
transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vert=
ical-align:baseline;white-space:pre-wrap">Throw ???</span></p></td></tr><tr=
style=3D"height:0pt"><td style=3D"border-width:1pt;border-style:solid;bord=
er-color:rgb(0,0,0);vertical-align:top;padding:5pt"><p dir=3D"ltr" style=3D=
"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-siz=
e:11pt;font-family:"Courier New";color:rgb(0,0,0);background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ve=
rtical-align:baseline;white-space:pre-wrap">m =3D c;</span></p></td><td sty=
le=3D"border-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-=
align:top;padding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:=
0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Cour=
ier New";color:rgb(0,0,0);background-color:transparent;font-variant-nu=
meric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-s=
pace:pre-wrap">*((C*)c.p) =3D *((C*)m.p);</span></p></td><td style=3D"borde=
r-width:1pt;border-style:solid;border-color:rgb(0,0,0);vertical-align:top;p=
adding:5pt"><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt;text-align:center"><span style=3D"font-size:11pt;font-family:Ari=
al;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">Copy</span></p></td></tr></tbody></table></div><br><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">Again we face an unacceptable undermining of u=
niqueness semantics; in addition we have changed the observable surface are=
a of assignment by necessitating a new runtime error reporting mechanism fo=
r when erased targets conflicting behavior, affecting the exception-safety =
of existing code.</span></p><h2 dir=3D"ltr" style=3D"line-height:1.38;margi=
n-top:18pt;margin-bottom:6pt"><span style=3D"font-size:16pt;font-family:Ari=
al;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap">Shallow v. Deep Const</span></h2><p dir=3D"ltr" style=
=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-=
size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;f=
ont-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:ba=
seline;white-space:pre-wrap">=E2=80=9CShallow=E2=80=9D or =E2=80=9CDeep=E2=
=80=9D const in a type erased context means whether the constness of the er=
asing type is extended towards the erased type. For our discussion we consi=
der whether the the erasing container is const callable if and only if the =
underlying type is const callable.</span></p><p dir=3D"ltr" style=3D"line-h=
eight:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;=
font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varian=
t-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whi=
te-space:pre-wrap"><br class=3D"m_-5373236172660489361m_-299560146663659952=
2m_-1335907127606806884m_-3924309839588613576gmail-kix-line-break"></span><=
span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-=
color:transparent;font-variant-numeric:normal;font-variant-east-asian:norma=
l;vertical-align:baseline;white-space:pre-wrap">It is by now understood tha=
t the standard requires const correctness to imply thread-safety, and if th=
e container operator() is const, the underlying callable type=E2=80=99s ope=
rator() must also be const in order to </span><span style=3D"font-size:11pt=
;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-style=
:italic;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap">hope</span><span style=3D"font-size:1=
1pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-va=
riant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline=
;white-space:pre-wrap"> of satisfying this obligation. So a shallow const c=
ontainer could not admit a thread-safe call operation in general, and both =
</span><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n=
4159.pdf" style=3D"text-decoration-line:none" target=3D"_blank"><span style=
=3D"font-size:11pt;font-family:Arial;background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;text-decoration-line:unde=
rline;vertical-align:baseline;white-space:pre-wrap">N4159</span></a><span s=
tyle=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:=
transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vert=
ical-align:baseline;white-space:pre-wrap"> and </span><a href=3D"http://www=
..open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0045r1.pdf" style=3D"text-de=
coration-line:none" target=3D"_blank"><span style=3D"font-size:11pt;font-fa=
mily:Arial;background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;text-decoration-line:underline;vertical-align:basel=
ine;white-space:pre-wrap">P0045R1</span></a><span style=3D"font-size:11pt;f=
ont-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant=
-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whit=
e-space:pre-wrap"> draw attention to the unfortunate outcome. The solution =
presented in those papers it to include the constness of the callable in si=
gnature, and to have the constness of container operator() be conditional o=
n the signature.</span><span style=3D"font-size:11pt;font-family:Arial;colo=
r:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-=
variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"><br=
class=3D"m_-5373236172660489361m_-2995601466636599522m_-133590712760680688=
4m_-3924309839588613576gmail-kix-line-break"><br class=3D"m_-53732361726604=
89361m_-2995601466636599522m_-1335907127606806884m_-3924309839588613576gmai=
l-kix-line-break"></span></p><p dir=3D"ltr" style=3D"line-height:1.38;margi=
n-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:&quo=
t;Courier New";color:rgb(0,0,0);background-color:transparent;font-vari=
ant-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;w=
hite-space:pre-wrap">struct Accessor {</span></p><p dir=3D"ltr" style=3D"li=
ne-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:1=
1pt;font-family:"Courier New";color:rgb(0,0,0);background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;verti=
cal-align:baseline;white-space:pre-wrap"> =C2=A0void operator()() const;</s=
pan></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bott=
om:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";c=
olor:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;fo=
nt-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">=
=C2=A0// ...</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top=
:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"Cou=
rier New";color:rgb(0,0,0);background-color:transparent;font-variant-n=
umeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-=
space:pre-wrap">} access;</span></p><br><p dir=3D"ltr" style=3D"line-height=
:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-=
family:"Courier New";color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap">struct Mutator {</span></p><p dir=3D"ltr" s=
tyle=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"f=
ont-size:11pt;font-family:"Courier New";color:rgb(0,0,0);backgrou=
nd-color:transparent;font-variant-numeric:normal;font-variant-east-asian:no=
rmal;vertical-align:baseline;white-space:pre-wrap"> =C2=A0void operator()()=
;</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap"> =C2=A0// ...</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin=
-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:"=
;Courier New";color:rgb(0,0,0);background-color:transparent;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap">} mutate;</span></p><br><p dir=3D"ltr" style=3D"line-he=
ight:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;f=
ont-family:"Courier New";color:rgb(0,0,0);background-color:transp=
arent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-a=
lign:baseline;white-space:pre-wrap">std3::function<void() const> a =
=3D access; =C2=A0// ok</span></p><p dir=3D"ltr" style=3D"line-height:1.38;=
margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family=
:"Courier New";color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap">std3::function<void()> b =3D access; =C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// ok</span></p><p dir=3D"ltr" style=3D=
"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-siz=
e:11pt;font-family:"Courier New";color:rgb(0,0,0);background-colo=
r:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ve=
rtical-align:baseline;white-space:pre-wrap">std3::function<void()> c =
=3D mutate; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0// ok</span></p><p di=
r=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span=
style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,=
0);background-color:transparent;font-variant-numeric:normal;font-variant-ea=
st-asian:normal;vertical-align:baseline;white-space:pre-wrap">std3::functio=
n<void() const> d =3D mutate; =C2=A0// compile error</span></p><br><p=
dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><s=
pan style=3D"font-size:11pt;font-family:"Courier New";color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">a =3D b; =
=C2=A0// compile error: target type more restrictive</span></p><p dir=3D"lt=
r" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:11pt;font-family:"Courier New";color:rgb(0,0,0);bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;vertical-align:baseline;white-space:pre-wrap">b =3D a; =C2=A0// o=
k</span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">b =3D c; =C2=A0// ok</span></p><p dir=3D"ltr" style=3D"line-height:1.38=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-famil=
y:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap"><br class=3D"m_-5373236172660489361m_-2995601466636599522m_-133590=
7127606806884m_-3924309839588613576gmail-kix-line-break"></span><span style=
=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap">This proposal, while in the author=E2=
=80=99s opinion is highly recommended improvement, it=E2=80=99s best presen=
ted in referenced papers, and for simplicity=E2=80=99s sake isn=E2=80=99t p=
ursued further here.</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38=
;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-famil=
y:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:=
normal;font-variant-east-asian:normal;vertical-align:baseline;white-space:p=
re-wrap">Otherwise, without the above but desiring deep const semantics, we=
would wish that const containers require const callable targets. However, =
since we have erase the constness of target instance, we are left with thro=
wing when deep const is violated, breaking existing exception-safe code.</s=
pan></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-=
bottom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New&quo=
t;;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:norma=
l;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wr=
ap">const std4::function<void()> a; =C2=A0=C2=A0=C2=A0// deep const</=
span></p><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bot=
tom:0pt"><span style=3D"font-size:11pt;font-family:"Courier New";=
color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;f=
ont-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap"=
>std::function<void()> b =3D mutate; =C2=A0// non-const target</span>=
</p><p dir=3D"ltr" style=3D"line-height:1.2;margin-top:0pt;margin-bottom:0p=
t"><span style=3D"font-size:11pt;font-family:"Courier New";color:=
rgb(0,0,0);background-color:transparent;font-variant-numeric:normal;font-va=
riant-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">a =3D=
b; =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0// target copied</span></p><p dir=3D"ltr" style=3D"=
line-height:1.2;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:=
11pt;font-family:"Courier New";color:rgb(0,0,0);background-color:=
transparent;font-variant-numeric:normal;font-variant-east-asian:normal;vert=
ical-align:baseline;white-space:pre-wrap">a(); =C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=
=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=
=A0// now throws!</span></p><h2 dir=3D"ltr" style=3D"line-height:1.38;margi=
n-top:18pt;margin-bottom:6pt"><span style=3D"font-size:16pt;font-family:Ari=
al;color:rgb(0,0,0);background-color:transparent;font-weight:400;font-varia=
nt-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;wh=
ite-space:pre-wrap">Necessity and Cost</span></h2><p dir=3D"ltr" style=3D"l=
ine-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:=
11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-v=
ariant-numeric:normal;font-variant-east-asian:normal;vertical-align:baselin=
e;white-space:pre-wrap">We can all agree type erased containers should supp=
ort as much as feasible the const correctness of its target types, but we b=
egan our argument with a specific asynchronous use case that involved defer=
red computations, often invoked on foreign threads. If this pattern as seen=
=E2=80=9Cin the wild=E2=80=9D makes use of thread safe queues, is thread s=
afety of the container itself actually sufficient to justify the costs asso=
ciated with extra synchronization or exception safety? Even if we can guara=
ntee const container only calls const target methods, we still cannot guara=
ntee the target itself makes the connection between const and thread safety=
..</span></p><br><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;mar=
gin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0=
,0,0);background-color:transparent;font-variant-numeric:normal;font-variant=
-east-asian:normal;vertical-align:baseline;white-space:pre-wrap">Should a p=
roposed std::unique_function emulate =E2=80=9Cbroken=E2=80=9D shallow const=
correctness of std::function for uniformity, or is =E2=80=9Cfixing=E2=80=
=9D the contradiction worth breaking runtime changes? And is std::unique_/f=
unction more like a container or pointer (where const is understood to be s=
hallow), or is it more like an opaque type (where const is generally consid=
ered to be deep)? Historically we allow container const to vary independent=
ly of parameterized types when they exist, suggesting std::function should =
remain a shallow container.</span></p><br><p dir=3D"ltr" style=3D"line-heig=
ht:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;fon=
t-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-n=
umeric:normal;font-variant-east-asian:normal;vertical-align:baseline;white-=
space:pre-wrap">While this question is relevant to the specification of std=
::unique_function, it is ultimately </span><span style=3D"font-size:11pt;fo=
nt-family:Arial;color:rgb(0,0,0);background-color:transparent;font-style:it=
alic;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-al=
ign:baseline;white-space:pre-wrap">orthogonal</span><span style=3D"font-siz=
e:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparent;font=
-variant-numeric:normal;font-variant-east-asian:normal;vertical-align:basel=
ine;white-space:pre-wrap"> to the question of the need for std::unique_func=
tion to exist, which is this paper=E2=80=99s main concern.</span></p><h1 di=
r=3D"ltr" style=3D"line-height:1.38;margin-top:20pt;margin-bottom:6pt"><spa=
n style=3D"font-size:20pt;font-family:Arial;color:rgb(0,0,0);background-col=
or:transparent;font-weight:400;font-variant-numeric:normal;font-variant-eas=
t-asian:normal;vertical-align:baseline;white-space:pre-wrap">Conclusion</sp=
an></h1><p dir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bott=
om:0pt"><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);ba=
ckground-color:transparent;font-variant-numeric:normal;font-variant-east-as=
ian:normal;vertical-align:baseline;white-space:pre-wrap">So long as we have=
move-only lambdas and type erased callable containers, a move-only capable=
std::function is required. As uniqueness semantics of container are orthog=
onal to const-correctness of the interface we recommend not conflating the =
two, and pursuing </span><a href=3D"http://www.open-std.org/jtc1/sc22/wg21/=
docs/papers/2017/p0045r1.pdf" style=3D"text-decoration-line:none" target=3D=
"_blank"><span style=3D"font-size:11pt;font-family:Arial;background-color:t=
ransparent;font-variant-numeric:normal;font-variant-east-asian:normal;text-=
decoration-line:underline;vertical-align:baseline;white-space:pre-wrap">P00=
45R1</span></a><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,=
0,0);background-color:transparent;font-variant-numeric:normal;font-variant-=
east-asian:normal;vertical-align:baseline;white-space:pre-wrap"> for const-=
correctness as an independent feature request.</span></p><h1 dir=3D"ltr" st=
yle=3D"line-height:1.38;margin-top:20pt;margin-bottom:6pt"><span style=3D"f=
ont-size:20pt;font-family:Arial;color:rgb(0,0,0);background-color:transpare=
nt;font-weight:400;font-variant-numeric:normal;font-variant-east-asian:norm=
al;vertical-align:baseline;white-space:pre-wrap">References</span></h1><p d=
ir=3D"ltr" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><spa=
n style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-col=
or:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;v=
ertical-align:baseline;white-space:pre-wrap">[1] </span><a href=3D"https://=
reviews.llvm.org/D48349" style=3D"text-decoration-line:none" target=3D"_bla=
nk"><span style=3D"font-size:11pt;font-family:Arial;background-color:transp=
arent;font-variant-numeric:normal;font-variant-east-asian:normal;text-decor=
ation-line:underline;vertical-align:baseline;white-space:pre-wrap">https://=
reviews.llvm.org/D48349</span></a></p><p dir=3D"ltr" style=3D"line-height:1=
..38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-fa=
mily:Arial;color:rgb(0,0,0);background-color:transparent;font-variant-numer=
ic:normal;font-variant-east-asian:normal;vertical-align:baseline;white-spac=
e:pre-wrap">[2] </span><a href=3D"http://llvm.org/doxygen/FunctionExtras_8h=
_source.html#l00046" style=3D"text-decoration-line:none" target=3D"_blank">=
<span style=3D"font-size:11pt;font-family:Arial;background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;text-decoratio=
n-line:underline;vertical-align:baseline;white-space:pre-wrap">http://llvm.=
org/doxygen/FunctionExtras_8h_source.html#l00046</span></a><span style=3D"f=
ont-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transpare=
nt;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-alig=
n:baseline;white-space:pre-wrap"> </span></p><p dir=3D"ltr" style=3D"line-h=
eight:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;=
font-family:Arial;color:rgb(0,0,0);background-color:transparent;font-varian=
t-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whi=
te-space:pre-wrap">[3] </span><a href=3D"https://github.com/STEllAR-GROUP/h=
px/blob/master/hpx/util/unique_function.hpp" style=3D"text-decoration-line:=
none" target=3D"_blank"><span style=3D"font-size:11pt;font-family:Arial;bac=
kground-color:transparent;font-variant-numeric:normal;font-variant-east-asi=
an:normal;text-decoration-line:underline;vertical-align:baseline;white-spac=
e:pre-wrap">https://github.com/STEllAR-GROUP/hpx/blob/master/hpx/util/uniqu=
e_function.hpp</span></a></p><p dir=3D"ltr" style=3D"line-height:1.38;margi=
n-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;font-family:Aria=
l;color:rgb(0,0,0);background-color:transparent;font-variant-numeric:normal=
;font-variant-east-asian:normal;vertical-align:baseline;white-space:pre-wra=
p">[4] </span><a href=3D"https://github.com/potswa/cxx_function/blob/master=
/cxx_function.hpp#L1192" style=3D"text-decoration-line:none" target=3D"_bla=
nk"><span style=3D"font-size:11pt;font-family:Arial;background-color:transp=
arent;font-variant-numeric:normal;font-variant-east-asian:normal;text-decor=
ation-line:underline;vertical-align:baseline;white-space:pre-wrap">https://=
github.com/potswa/cxx_function/blob/master/cxx_function.hpp#L1192</span></a=
><span style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);backgroun=
d-color:transparent;font-variant-numeric:normal;font-variant-east-asian:nor=
mal;vertical-align:baseline;white-space:pre-wrap"> </span></p><p dir=3D"ltr=
" style=3D"line-height:1.38;margin-top:0pt;margin-bottom:0pt"><span style=
=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:tran=
sparent;font-variant-numeric:normal;font-variant-east-asian:normal;vertical=
-align:baseline;white-space:pre-wrap">[5] </span><a href=3D"https://github.=
com/Naios/function2/blob/master/include/function2/function2.hpp#L1406" styl=
e=3D"text-decoration-line:none" target=3D"_blank"><span style=3D"font-size:=
11pt;font-family:Arial;background-color:transparent;font-variant-numeric:no=
rmal;font-variant-east-asian:normal;text-decoration-line:underline;vertical=
-align:baseline;white-space:pre-wrap">https://github.com/Naios/function2/bl=
ob/master/include/function2/function2.hpp#L1406</span></a><span style=3D"fo=
nt-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color:transparen=
t;font-variant-numeric:normal;font-variant-east-asian:normal;vertical-align=
:baseline;white-space:pre-wrap"> </span></p><p dir=3D"ltr" style=3D"line-he=
ight:1.38;margin-top:0pt;margin-bottom:0pt"><span style=3D"font-size:11pt;f=
ont-family:Arial;color:rgb(0,0,0);background-color:transparent;font-variant=
-numeric:normal;font-variant-east-asian:normal;vertical-align:baseline;whit=
e-space:pre-wrap">[6] </span><a href=3D"https://github.com/facebook/folly/b=
lob/master/folly/Function.h" style=3D"text-decoration-line:none" target=3D"=
_blank"><span style=3D"font-size:11pt;font-family:Arial;background-color:tr=
ansparent;font-variant-numeric:normal;font-variant-east-asian:normal;text-d=
ecoration-line:underline;vertical-align:baseline;white-space:pre-wrap">http=
s://github.com/facebook/folly/blob/master/folly/Function.h</span></a><span =
style=3D"font-size:11pt;font-family:Arial;color:rgb(0,0,0);background-color=
:transparent;font-variant-numeric:normal;font-variant-east-asian:normal;ver=
tical-align:baseline;white-space:pre-wrap"> </span></p></span><br class=3D"=
m_-5373236172660489361m_-2995601466636599522m_-1335907127606806884m_-392430=
9839588613576gmail-Apple-interchange-newline"></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" target=3D"_=
blank">std-proposals+unsubscribe@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/CAHn%2BA5NyaUQjAeudtObjn08Trz4iJ%2Bu-=
GGt2J5VnmtmZJiPVxg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-p=
roposals/CAHn%2BA5NyaUQjAeudtObjn08Trz4iJ%2Bu-GGt2J5VnmtmZJiPVxg%40mail.gma=
il.com</a>.<br>
</blockquote></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" target=3D"_=
blank">std-proposals+unsubscribe@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/CAJH_FNW1PVw2BeYJCWfKNKN3_67eLY_6wG1v=
gNJOZx9oQS%2Bs%3DQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-p=
roposals/CAJH_FNW1PVw2BeYJCWfKNKN3_67eLY_6wG1vgNJOZx9oQS%2Bs%3DQ%40mail.gma=
il.com</a>.<br>
</blockquote></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" target=3D"_=
blank">std-proposals+unsubscribe@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/CAHn%2BA5NHiEO1rTKfZOryWnW-NTqLGgim6e=
pp-Bt03iU5wd-EEA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-pro=
posals/CAHn%2BA5NHiEO1rTKfZOryWnW-NTqLGgim6epp-Bt03iU5wd-EEA%40mail.gmail.c=
om</a>.<br>
</blockquote></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" target=3D"_=
blank">std-proposals+unsubscribe@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/CAJH_FNWs-rP4hc6V3pE1vTgQgtTUKfNsJOmO=
zsxWvwRzsC2ywA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-propo=
sals/CAJH_FNWs-rP4hc6V3pE1vTgQgtTUKfNsJOmOzsxWvwRzsC2ywA%40mail.gmail.com</=
a>.<br>
</blockquote></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/CAHn%2BA5PiWBuc33MR6Sr%2BvU4W%3DWtcEN=
vMc4Nf%2BYP-8joBNPnYQw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHn%2BA5=
PiWBuc33MR6Sr%2BvU4W%3DWtcENvMc4Nf%2BYP-8joBNPnYQw%40mail.gmail.com</a>.<br=
/>
--000000000000b52ed10578e7e979--
.
Author: Lee Howes <xrikcus@gmail.com>
Date: Tue, 23 Oct 2018 09:35:23 -0700
Raw View
--000000000000783f700578e7f502
Content-Type: text/plain; charset="UTF-8"
A new revision of David Krauss's paper seems like the cleanest approach to
preserve history in discussions, but yes, we can definitely talk in SD.
There will be a few of us there.
--
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/CAJH_FNUBdcsx5tQa6kYLhpPO8aGck_4dG3t18Ytdh%3DfWPHTbsA%40mail.gmail.com.
--000000000000783f700578e7f502
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">A new revision of David Krauss's paper seems like the =
cleanest approach to preserve history in discussions, but yes, we can defin=
itely talk in SD. There will be a few of us there.=C2=A0</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/CAJH_FNUBdcsx5tQa6kYLhpPO8aGck_4dG3t1=
8Ytdh%3DfWPHTbsA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJH_FNUBdcsx5t=
Qa6kYLhpPO8aGck_4dG3t18Ytdh%3DfWPHTbsA%40mail.gmail.com</a>.<br />
--000000000000783f700578e7f502--
.
Author: Ryan McDougall <mcdougall.ryan@gmail.com>
Date: Tue, 23 Oct 2018 09:37:34 -0700
Raw View
--0000000000005354590578e7fd89
Content-Type: text/plain; charset="UTF-8"
My understanding is David doesn't develop C++ anymore. Do you suggest we
re-write/update his paper?
On Tue, Oct 23, 2018 at 9:35 AM Lee Howes <xrikcus@gmail.com> wrote:
> A new revision of David Krauss's paper seems like the cleanest approach to
> preserve history in discussions, but yes, we can definitely talk in SD.
> There will be a few of us there.
>
> --
> 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/CAJH_FNUBdcsx5tQa6kYLhpPO8aGck_4dG3t18Ytdh%3DfWPHTbsA%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJH_FNUBdcsx5tQa6kYLhpPO8aGck_4dG3t18Ytdh%3DfWPHTbsA%40mail.gmail.com?utm_medium=email&utm_source=footer>
> .
>
--
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/CAHn%2BA5Ppq%3D7_oB_do2eLjxe2RP-gWRRwdTYtuz-sZ7p%2BQq-pVw%40mail.gmail.com.
--0000000000005354590578e7fd89
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">My understanding is David doesn't develop C++ anymore.=
Do you suggest we re-write/update his paper?</div><br><div class=3D"gmail_=
quote"><div dir=3D"ltr">On Tue, Oct 23, 2018 at 9:35 AM Lee Howes <<a hr=
ef=3D"mailto:xrikcus@gmail.com">xrikcus@gmail.com</a>> wrote:<br></div><=
blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px=
#ccc solid;padding-left:1ex"><div dir=3D"ltr">A new revision of David Krau=
ss's paper seems like the cleanest approach to preserve history in disc=
ussions, but yes, we can definitely talk in SD. There will be a few of us t=
here.=C2=A0</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" target=3D"_=
blank">std-proposals+unsubscribe@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/CAJH_FNUBdcsx5tQa6kYLhpPO8aGck_4dG3t1=
8Ytdh%3DfWPHTbsA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-pro=
posals/CAJH_FNUBdcsx5tQa6kYLhpPO8aGck_4dG3t18Ytdh%3DfWPHTbsA%40mail.gmail.c=
om</a>.<br>
</blockquote></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/CAHn%2BA5Ppq%3D7_oB_do2eLjxe2RP-gWRRw=
dTYtuz-sZ7p%2BQq-pVw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHn%2BA5Pp=
q%3D7_oB_do2eLjxe2RP-gWRRwdTYtuz-sZ7p%2BQq-pVw%40mail.gmail.com</a>.<br />
--0000000000005354590578e7fd89--
.
Author: Lee Howes <xrikcus@gmail.com>
Date: Tue, 23 Oct 2018 09:57:09 -0700
Raw View
--00000000000049cb9a0578e843c6
Content-Type: text/plain; charset="UTF-8"
Well that was what I was thinking, but it's really up to you. I'm probably
not the right person to advise on LEWG procedure so I could easily be
giving the wrong advice anyway.
--
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/CAJH_FNWHNbz4WzoakMi%2B-drrUKwrMnQKs3QQytBpdL-zgirKtg%40mail.gmail.com.
--00000000000049cb9a0578e843c6
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Well that was what I was thinking, but it's really up =
to you. I'm probably not the right person to advise on LEWG procedure s=
o I could easily be giving the wrong advice anyway.</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/CAJH_FNWHNbz4WzoakMi%2B-drrUKwrMnQKs3=
QQytBpdL-zgirKtg%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAJH_FNWHNbz4Wz=
oakMi%2B-drrUKwrMnQKs3QQytBpdL-zgirKtg%40mail.gmail.com</a>.<br />
--00000000000049cb9a0578e843c6--
.
Author: Brian Budge <bbudge@fb.com>
Date: Tue, 23 Oct 2018 17:35:27 +0000
Raw View
--_000_MW2PR1501MB2154FB67DE8B9F102CC016EEA2F50MW2PR1501MB2154_
Content-Type: text/plain; charset="UTF-8"
David suggested to reach out to Jeffrey Yasskin on LEWG to loop him into the discussion.
Get Outlook for Android<https://aka.ms/ghei36>
________________________________
From: Lee Howes <xrikcus@gmail.com>
Sent: Tuesday, October 23, 2018 9:57:09 AM
To: std-proposals@isocpp.org
Cc: Brian Budge
Subject: Re: [std-proposals] The need for std::unique_function
Well that was what I was thinking, but it's really up to you. I'm probably not the right person to advise on LEWG procedure so I could easily be giving the wrong advice anyway.
--
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/MW2PR1501MB2154FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.com.
--_000_MW2PR1501MB2154FB67DE8B9F102CC016EEA2F50MW2PR1501MB2154_
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<html>
<head>
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dus-ascii"=
>
<meta content=3D"text/html; charset=3Dutf-8">
</head>
<body>
<div dir=3D"auto" style=3D"direction:ltr; margin:0; padding:0; font-family:=
sans-serif; font-size:11pt; color:black">
David suggested to reach out to Jeffrey Yasskin on LEWG to loop him into th=
e discussion.<br>
<br>
</div>
<div dir=3D"auto" style=3D"direction:ltr; margin:0; padding:0; font-family:=
sans-serif; font-size:11pt; color:black">
<div dir=3D"auto" style=3D"direction:ltr; margin:0; padding:0; font-family:=
sans-serif; font-size:11pt; color:black">
Get <a href=3D"https://aka.ms/ghei36">Outlook for Android</a></div>
<br>
</div>
<hr tabindex=3D"-1" style=3D"display:inline-block; width:98%">
<div id=3D"divRplyFwdMsg" dir=3D"ltr"><font face=3D"Calibri, sans-serif" co=
lor=3D"#000000" style=3D"font-size:11pt"><b>From:</b> Lee Howes <xrikcus=
@gmail.com><br>
<b>Sent:</b> Tuesday, October 23, 2018 9:57:09 AM<br>
<b>To:</b> std-proposals@isocpp.org<br>
<b>Cc:</b> Brian Budge<br>
<b>Subject:</b> Re: [std-proposals] The need for std::unique_function</font=
>
<div> </div>
</div>
<div>
<div dir=3D"ltr">Well that was what I was thinking, but it's really up to y=
ou. I'm probably not the right person to advise on LEWG procedure so I coul=
d easily be giving the wrong advice anyway.</div>
</div>
</body>
</html>
<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/MW2PR1501MB2154FB67DE8B9F102CC016EEA2=
F50%40MW2PR1501MB2154.namprd15.prod.outlook.com?utm_medium=3Demail&utm_sour=
ce=3Dfooter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/M=
W2PR1501MB2154FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.out=
look.com</a>.<br />
--_000_MW2PR1501MB2154FB67DE8B9F102CC016EEA2F50MW2PR1501MB2154_--
.
Author: "'David Krauss' via ISO C++ Standard - Future Proposals" <std-proposals@isocpp.org>
Date: Tue, 23 Oct 2018 22:59:38 +0200
Raw View
--Apple-Mail=_7F7A9ACF-6361-4432-92E5-3C6F844E4DCE
Content-Transfer-Encoding: quoted-printable
Content-Type: text/plain; charset="UTF-8"
Hi Ryan, all,
Thanks for your support! I=E2=80=99m not an active user of C++ and I won=E2=
=80=99t be attending the next conference, but anyone can certainly still pi=
ng me.
Feel free to carry over the P0288 number. The main work to align the P0288 =
draft with your proposal would be rebasing the standardese onto the IS, fro=
m the current basis of P0045. Most of this can be done by recovering the te=
xt from P0288R0.
The rationale for P0288R1 depending on P0045 was that the shallow-const iss=
ue was spreading to this new class as a virus, so the fix in P0045 should b=
e applied first to contain the damage. However, two years have passed with =
less interest in P0045 (or another deep-const fix; adding deep const does n=
ot imply all of P0045). The fixed, dependent version P0288R1 was never pres=
ented =E2=80=94 several volunteers have come forward but the extra complica=
tion has been a hindrance.
We might focus now on building LEWG consensus on the order of dependencies.=
We=E2=80=99ve missed 2018 and there=E2=80=99s still plenty of time before =
Kona 2019. If some committee members are serious about deep const as a hard=
requirement, then they have ample opportunity to support P0045 or to inven=
t another solution. Otherwise, everyone should be able to agree on a standa=
lone unique_function.
- Best,
David
> On 2018=E2=80=9310=E2=80=9323, at 7:35 PM, Brian Budge <bbudge@fb.com> wr=
ote:
>=20
> David suggested to reach out to Jeffrey Yasskin on LEWG to loop him into =
the discussion.
>=20
> Get Outlook for Android <https://aka.ms/ghei36>
> From: Lee Howes <xrikcus@gmail.com>
> Sent: Tuesday, October 23, 2018 9:57:09 AM
> To: std-proposals@isocpp.org
> Cc: Brian Budge
> Subject: Re: [std-proposals] The need for std::unique_function
> =20
> Well that was what I was thinking, but it's really up to you. I'm probabl=
y not the right person to advise on LEWG procedure so I could easily be giv=
ing the wrong advice anyway.
>=20
> --=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=
email to std-proposals+unsubscribe@isocpp.org <mailto:std-proposals+unsubs=
cribe@isocpp.org>.
> To post to this group, send email to std-proposals@isocpp.org <mailto:std=
-proposals@isocpp.org>.
> To view this discussion on the web visit https://groups.google.com/a/isoc=
pp.org/d/msgid/std-proposals/MW2PR1501MB2154FB67DE8B9F102CC016EEA2F50%40MW2=
PR1501MB2154.namprd15.prod.outlook.com <https://groups.google.com/a/isocpp.=
org/d/msgid/std-proposals/MW2PR1501MB2154FB67DE8B9F102CC016EEA2F50%40MW2PR1=
501MB2154.namprd15.prod.outlook.com?utm_medium=3Demail&utm_source=3Dfooter>=
..
--=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/DF91B617-FD32-486E-A5B4-65AB33809C5B%40me.com.
--Apple-Mail=_7F7A9ACF-6361-4432-92E5-3C6F844E4DCE
Content-Transfer-Encoding: quoted-printable
Content-Type: text/html; charset="UTF-8"
<html><head><meta http-equiv=3D"Content-Type" content=3D"text/html charset=
=3Dutf-8"></head><body style=3D"word-wrap: break-word; -webkit-nbsp-mode: s=
pace; -webkit-line-break: after-white-space;" class=3D"">Hi Ryan, all,<div =
class=3D""><br class=3D""></div><div class=3D"">Thanks for your support! I=
=E2=80=99m not an active user of C++ and I won=E2=80=99t be attending the n=
ext conference, but anyone can certainly still ping me.</div><div class=3D"=
"><br class=3D""></div><div class=3D"">Feel free to carry over the P0288 nu=
mber. The main work to align the P0288 draft with your proposal would be re=
basing the standardese onto the IS, from the current basis of P0045. Most o=
f this can be done by recovering the text from P0288R0.</div><div class=3D"=
"><br class=3D""></div><div class=3D"">The rationale for P0288R1 depending =
on P0045 was that the shallow-const issue was spreading to this new class a=
s a virus, so the fix in P0045 should be applied first to contain the damag=
e. However, two years have passed with less interest in P0045 (or another d=
eep-const fix; adding deep const does not imply all of P0045). The fixed, d=
ependent version P0288R1 was never presented =E2=80=94 several volunteers h=
ave come forward but the extra complication has been a hindrance.</div><div=
class=3D""><br class=3D""></div><div class=3D"">We might focus now on buil=
ding LEWG consensus on the order of dependencies. We=E2=80=99ve missed 2018=
and there=E2=80=99s still plenty of time before Kona 2019. If some committ=
ee members are serious about deep const as a hard requirement, then they ha=
ve ample opportunity to support P0045 or to invent another solution. Otherw=
ise, everyone should be able to agree on a standalone <font face=3D"Courier=
" class=3D"">unique_function</font>.</div><div class=3D""><br class=3D""></=
div><div class=3D""><span class=3D"Apple-tab-span" style=3D"white-space:pre=
"> </span>- Best,</div><div class=3D""><span class=3D"Apple-tab-span" style=
=3D"white-space:pre"> </span>David</div><div class=3D""><br class=3D""></di=
v><div class=3D""><br class=3D""><div><blockquote type=3D"cite" class=3D"">=
<div class=3D"">On 2018=E2=80=9310=E2=80=9323, at 7:35 PM, Brian Budge <=
<a href=3D"mailto:bbudge@fb.com" class=3D"">bbudge@fb.com</a>> wrote:</d=
iv><br class=3D"Apple-interchange-newline"><div class=3D"">
<meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dus-ascii"=
class=3D"">
<meta content=3D"text/html; charset=3Dutf-8" class=3D"">
<div class=3D"">
<div dir=3D"auto" style=3D"direction: ltr; margin: 0px; padding: 0px; font-=
family: sans-serif; font-size: 11pt;" class=3D"">
David suggested to reach out to Jeffrey Yasskin on LEWG to loop him into th=
e discussion.<br class=3D"">
<br class=3D"">
</div>
<div dir=3D"auto" style=3D"direction: ltr; margin: 0px; padding: 0px; font-=
family: sans-serif; font-size: 11pt;" class=3D"">
<div dir=3D"auto" style=3D"direction: ltr; margin: 0px; padding: 0px; font-=
family: sans-serif; font-size: 11pt;" class=3D"">
Get <a href=3D"https://aka.ms/ghei36" class=3D"">Outlook for Android</a></d=
iv>
<br class=3D"">
</div>
<hr tabindex=3D"-1" style=3D"display:inline-block; width:98%" class=3D"">
<div id=3D"divRplyFwdMsg" dir=3D"ltr" class=3D""><font face=3D"Calibri, san=
s-serif" style=3D"font-size:11pt" class=3D""><b class=3D"">From:</b> Lee Ho=
wes <<a href=3D"mailto:xrikcus@gmail.com" class=3D"">xrikcus@gmail.com</=
a>><br class=3D"">
<b class=3D"">Sent:</b> Tuesday, October 23, 2018 9:57:09 AM<br class=3D"">
<b class=3D"">To:</b> <a href=3D"mailto:std-proposals@isocpp.org" class=3D"=
">std-proposals@isocpp.org</a><br class=3D"">
<b class=3D"">Cc:</b> Brian Budge<br class=3D"">
<b class=3D"">Subject:</b> Re: [std-proposals] The need for std::unique_fun=
ction</font>
<div class=3D""> </div>
</div>
<div class=3D"">
<div dir=3D"ltr" class=3D"">Well that was what I was thinking, but it's rea=
lly up to you. I'm probably not the right person to advise on LEWG procedur=
e so I could easily be giving the wrong advice anyway.</div>
</div>
</div><div class=3D""><br class=3D"webkit-block-placeholder"></div>
-- <br class=3D"">
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.<br class=3D"">
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" class=3D"">=
std-proposals+unsubscribe@isocpp.org</a>.<br class=3D"">
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" class=3D"">std-proposals@isocpp.org</a>.<br class=3D"">
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/MW2PR1501MB2154FB67DE8B9F102CC016EEA2=
F50%40MW2PR1501MB2154.namprd15.prod.outlook.com?utm_medium=3Demail&utm_=
source=3Dfooter" class=3D"">https://groups.google.com/a/isocpp.org/d/msgid/=
std-proposals/MW2PR1501MB2154FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.na=
mprd15.prod.outlook.com</a>.<br class=3D"">
</div></blockquote></div><br class=3D""></div></body></html>
<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/DF91B617-FD32-486E-A5B4-65AB33809C5B%=
40me.com?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.com/=
a/isocpp.org/d/msgid/std-proposals/DF91B617-FD32-486E-A5B4-65AB33809C5B%40m=
e.com</a>.<br />
--Apple-Mail=_7F7A9ACF-6361-4432-92E5-3C6F844E4DCE--
.
Author: Bryce Adelstein Lelbach aka wash <brycelelbach@gmail.com>
Date: Tue, 23 Oct 2018 23:59:47 -0700
Raw View
--000000000000d929e10578f408ac
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
I would be willing to allocate time in LEWGI at San Diego to see this
paper, as it's a frequently requested feature.
This comes with the caveat I'd like one updated proposal for this, intended
for discussion ready for circulation on the LEWG reflector by this Friday.
On Tue, Oct 23, 2018, 1:59 PM 'David Krauss' via ISO C++ Standard - Future
Proposals <std-proposals@isocpp.org> wrote:
> Hi Ryan, all,
>
> Thanks for your support! I=E2=80=99m not an active user of C++ and I won=
=E2=80=99t be
> attending the next conference, but anyone can certainly still ping me.
>
> Feel free to carry over the P0288 number. The main work to align the P028=
8
> draft with your proposal would be rebasing the standardese onto the IS,
> from the current basis of P0045. Most of this can be done by recovering t=
he
> text from P0288R0.
>
> The rationale for P0288R1 depending on P0045 was that the shallow-const
> issue was spreading to this new class as a virus, so the fix in P0045
> should be applied first to contain the damage. However, two years have
> passed with less interest in P0045 (or another deep-const fix; adding dee=
p
> const does not imply all of P0045). The fixed, dependent version P0288R1
> was never presented =E2=80=94 several volunteers have come forward but th=
e extra
> complication has been a hindrance.
>
> We might focus now on building LEWG consensus on the order of
> dependencies. We=E2=80=99ve missed 2018 and there=E2=80=99s still plenty =
of time before
> Kona 2019. If some committee members are serious about deep const as a ha=
rd
> requirement, then they have ample opportunity to support P0045 or to inve=
nt
> another solution. Otherwise, everyone should be able to agree on a
> standalone unique_function.
>
> - Best,
> David
>
>
> On 2018=E2=80=9310=E2=80=9323, at 7:35 PM, Brian Budge <bbudge@fb.com> wr=
ote:
>
> David suggested to reach out to Jeffrey Yasskin on LEWG to loop him into
> the discussion.
>
> Get Outlook for Android <https://aka.ms/ghei36>
>
> ------------------------------
> *From:* Lee Howes <xrikcus@gmail.com>
> *Sent:* Tuesday, October 23, 2018 9:57:09 AM
> *To:* std-proposals@isocpp.org
> *Cc:* Brian Budge
> *Subject:* Re: [std-proposals] The need for std::unique_function
>
> Well that was what I was thinking, but it's really up to you. I'm probabl=
y
> not the right person to advise on LEWG procedure so I could easily be
> giving the wrong advice anyway.
>
> --
> 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/MW2PR1501MB2=
154FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/MW2PR1501MB=
2154FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.com?u=
tm_medium=3Demail&utm_source=3Dfooter>
> .
>
>
> --
> 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/DF91B617-FD3=
2-486E-A5B4-65AB33809C5B%40me.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/DF91B617-FD=
32-486E-A5B4-65AB33809C5B%40me.com?utm_medium=3Demail&utm_source=3Dfooter>
> .
>
--=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/CAP3wax9WPkgz5_E1iS_bJf5HD69Qf17XqYRYxX%3DzXHOfp=
AcK-g%40mail.gmail.com.
--000000000000d929e10578f408ac
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"auto"><div>I would be willing to allocate time in LEWGI at San =
Diego to see this paper, as it's a frequently requested feature.<div di=
r=3D"auto"><br></div><div dir=3D"auto">This comes with the caveat I'd l=
ike one updated proposal for this, intended for discussion ready for circul=
ation on the LEWG reflector by this Friday.</div><div dir=3D"auto"><br></di=
v><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Tue, Oct 23, 2018, 1:5=
9 PM 'David Krauss' via ISO C++ Standard - Future Proposals <<a =
href=3D"mailto:std-proposals@isocpp.org">std-proposals@isocpp.org</a>> w=
rote:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex=
;border-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break=
-word">Hi Ryan, all,<div><br></div><div>Thanks for your support! I=E2=80=99=
m not an active user of C++ and I won=E2=80=99t be attending the next confe=
rence, but anyone can certainly still ping me.</div><div><br></div><div>Fee=
l free to carry over the P0288 number. The main work to align the P0288 dra=
ft with your proposal would be rebasing the standardese onto the IS, from t=
he current basis of P0045. Most of this can be done by recovering the text =
from P0288R0.</div><div><br></div><div>The rationale for P0288R1 depending =
on P0045 was that the shallow-const issue was spreading to this new class a=
s a virus, so the fix in P0045 should be applied first to contain the damag=
e. However, two years have passed with less interest in P0045 (or another d=
eep-const fix; adding deep const does not imply all of P0045). The fixed, d=
ependent version P0288R1 was never presented =E2=80=94 several volunteers h=
ave come forward but the extra complication has been a hindrance.</div><div=
><br></div><div>We might focus now on building LEWG consensus on the order =
of dependencies. We=E2=80=99ve missed 2018 and there=E2=80=99s still plenty=
of time before Kona 2019. If some committee members are serious about deep=
const as a hard requirement, then they have ample opportunity to support P=
0045 or to invent another solution. Otherwise, everyone should be able to a=
gree on a standalone <font face=3D"Courier">unique_function</font>.</div><d=
iv><br></div><div><span class=3D"m_-1270531741872738342Apple-tab-span" styl=
e=3D"white-space:pre-wrap"> </span>- Best,</div><div><span class=3D"m_-1270=
531741872738342Apple-tab-span" style=3D"white-space:pre-wrap"> </span>David=
</div><div><br></div><div><br><div><blockquote type=3D"cite"><div>On 2018=
=E2=80=9310=E2=80=9323, at 7:35 PM, Brian Budge <<a href=3D"mailto:bbudg=
e@fb.com" target=3D"_blank" rel=3D"noreferrer">bbudge@fb.com</a>> wrote:=
</div><br class=3D"m_-1270531741872738342Apple-interchange-newline"><div>
<div>
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
David suggested to reach out to Jeffrey Yasskin on LEWG to loop him into th=
e discussion.<br>
<br>
</div>
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
Get <a href=3D"https://aka.ms/ghei36" target=3D"_blank" rel=3D"noreferrer">=
Outlook for Android</a></div>
<br>
</div>
<hr style=3D"display:inline-block;width:98%">
<div id=3D"m_-1270531741872738342divRplyFwdMsg" dir=3D"ltr"><font face=3D"C=
alibri, sans-serif" style=3D"font-size:11pt"><b>From:</b> Lee Howes <<a =
href=3D"mailto:xrikcus@gmail.com" target=3D"_blank" rel=3D"noreferrer">xrik=
cus@gmail.com</a>><br>
<b>Sent:</b> Tuesday, October 23, 2018 9:57:09 AM<br>
<b>To:</b> <a href=3D"mailto:std-proposals@isocpp.org" target=3D"_blank" re=
l=3D"noreferrer">std-proposals@isocpp.org</a><br>
<b>Cc:</b> Brian Budge<br>
<b>Subject:</b> Re: [std-proposals] The need for std::unique_function</font=
>
<div>=C2=A0</div>
</div>
<div>
<div dir=3D"ltr">Well that was what I was thinking, but it's really up =
to you. I'm probably not the right person to advise on LEWG procedure s=
o I could easily be giving the wrong advice anyway.</div>
</div>
</div><div><br class=3D"m_-1270531741872738342webkit-block-placeholder"></d=
iv>
-- <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" rel=3D"noreferrer">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank" rel=3D"noreferrer">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/MW2PR1501MB2154FB67DE8B9F102CC016EEA2=
F50%40MW2PR1501MB2154.namprd15.prod.outlook.com?utm_medium=3Demail&utm_=
source=3Dfooter" target=3D"_blank" rel=3D"noreferrer">https://groups.google=
..com/a/isocpp.org/d/msgid/std-proposals/MW2PR1501MB2154FB67DE8B9F102CC016EE=
A2F50%40MW2PR1501MB2154.namprd15.prod.outlook.com</a>.<br>
</div></blockquote></div><br></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" target=3D"_=
blank" rel=3D"noreferrer">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank" rel=3D"noreferrer">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/DF91B617-FD32-486E-A5B4-65AB33809C5B%=
40me.com?utm_medium=3Demail&utm_source=3Dfooter" target=3D"_blank" rel=
=3D"noreferrer">https://groups.google.com/a/isocpp.org/d/msgid/std-proposal=
s/DF91B617-FD32-486E-A5B4-65AB33809C5B%40me.com</a>.<br>
</blockquote></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/CAP3wax9WPkgz5_E1iS_bJf5HD69Qf17XqYRY=
xX%3DzXHOfpAcK-g%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAP3wax9WPkgz5_=
E1iS_bJf5HD69Qf17XqYRYxX%3DzXHOfpAcK-g%40mail.gmail.com</a>.<br />
--000000000000d929e10578f408ac--
.
Author: Ryan McDougall <mcdougall.ryan@gmail.com>
Date: Wed, 24 Oct 2018 09:41:11 -0700
Raw View
--0000000000001ff3010578fc28b2
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
From my point of view there are 2 issues:
1) Do we need std::unique_function: Yes
2) Do we want it to be move-only version of std::function, or should it be
improved version where
```std::unique_function<void() const> f;``` only admits targets with const
callable operators?
I think there's legitimate debate about latter, but it should not preclude
the former. Should I just present it as an open question?
Lastly standardese. I don't speak it at all (yet). I can simply lift
David's -- is that acceptable?
To recapitulate:
- Rename to P0288
- Fold in P0045 as an option
- Steal P0045 standardese
- Ready by friday
^ This is the request?
On Wed, Oct 24, 2018 at 12:00 AM Bryce Adelstein Lelbach aka wash <
brycelelbach@gmail.com> wrote:
> I would be willing to allocate time in LEWGI at San Diego to see this
> paper, as it's a frequently requested feature.
>
> This comes with the caveat I'd like one updated proposal for this,
> intended for discussion ready for circulation on the LEWG reflector by th=
is
> Friday.
>
>
> On Tue, Oct 23, 2018, 1:59 PM 'David Krauss' via ISO C++ Standard - Futur=
e
> Proposals <std-proposals@isocpp.org> wrote:
>
>> Hi Ryan, all,
>>
>> Thanks for your support! I=E2=80=99m not an active user of C++ and I won=
=E2=80=99t be
>> attending the next conference, but anyone can certainly still ping me.
>>
>> Feel free to carry over the P0288 number. The main work to align the
>> P0288 draft with your proposal would be rebasing the standardese onto th=
e
>> IS, from the current basis of P0045. Most of this can be done by recover=
ing
>> the text from P0288R0.
>>
>> The rationale for P0288R1 depending on P0045 was that the shallow-const
>> issue was spreading to this new class as a virus, so the fix in P0045
>> should be applied first to contain the damage. However, two years have
>> passed with less interest in P0045 (or another deep-const fix; adding de=
ep
>> const does not imply all of P0045). The fixed, dependent version P0288R1
>> was never presented =E2=80=94 several volunteers have come forward but t=
he extra
>> complication has been a hindrance.
>>
>> We might focus now on building LEWG consensus on the order of
>> dependencies. We=E2=80=99ve missed 2018 and there=E2=80=99s still plenty=
of time before
>> Kona 2019. If some committee members are serious about deep const as a h=
ard
>> requirement, then they have ample opportunity to support P0045 or to inv=
ent
>> another solution. Otherwise, everyone should be able to agree on a
>> standalone unique_function.
>>
>> - Best,
>> David
>>
>>
>> On 2018=E2=80=9310=E2=80=9323, at 7:35 PM, Brian Budge <bbudge@fb.com> w=
rote:
>>
>> David suggested to reach out to Jeffrey Yasskin on LEWG to loop him into
>> the discussion.
>>
>> Get Outlook for Android <https://aka.ms/ghei36>
>>
>> ------------------------------
>> *From:* Lee Howes <xrikcus@gmail.com>
>> *Sent:* Tuesday, October 23, 2018 9:57:09 AM
>> *To:* std-proposals@isocpp.org
>> *Cc:* Brian Budge
>> *Subject:* Re: [std-proposals] The need for std::unique_function
>>
>> Well that was what I was thinking, but it's really up to you. I'm
>> probably not the right person to advise on LEWG procedure so I could eas=
ily
>> be giving the wrong advice anyway.
>>
>> --
>> You received this message because you are subscribed to the Google Group=
s
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> 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/MW2PR1501MB=
2154FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.com
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/MW2PR1501M=
B2154FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.com?=
utm_medium=3Demail&utm_source=3Dfooter>
>> .
>>
>>
>> --
>> You received this message because you are subscribed to the Google Group=
s
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> 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/DF91B617-FD=
32-486E-A5B4-65AB33809C5B%40me.com
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/DF91B617-F=
D32-486E-A5B4-65AB33809C5B%40me.com?utm_medium=3Demail&utm_source=3Dfooter>
>> .
>>
>
--=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/CAHn%2BA5MCw%3D5ebSe8zwTSd35GP03dTpvtGv-X_vS4j1u=
jmEMyFQ%40mail.gmail.com.
--0000000000001ff3010578fc28b2
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">From my point of view there are 2 issues:<div>1) Do we nee=
d std::unique_function: Yes<br>2) Do we want it to be move-only version of =
std::function, or should it be improved version where<br>```std::unique_fun=
ction<void() const> f;``` only admits targets with const callable ope=
rators?<br><br>I think there's legitimate debate about latter, but it s=
hould not preclude the former. Should I just present it as an open question=
?<br><br>Lastly standardese. I don't speak it at all (yet). I can simpl=
y lift David's -- is that acceptable?<br><br>To recapitulate:<br>- Rena=
me to P0288<br>- Fold in P0045 as an option<br>- Steal P0045 standardese<br=
>- Ready by friday<br><br>^ This is the request?</div></div><br><div class=
=3D"gmail_quote"><div dir=3D"ltr">On Wed, Oct 24, 2018 at 12:00 AM Bryce Ad=
elstein Lelbach aka wash <<a href=3D"mailto:brycelelbach@gmail.com">bryc=
elelbach@gmail.com</a>> wrote:<br></div><blockquote class=3D"gmail_quote=
" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><=
div dir=3D"auto"><div>I would be willing to allocate time in LEWGI at San D=
iego to see this paper, as it's a frequently requested feature.<div dir=
=3D"auto"><br></div><div dir=3D"auto">This comes with the caveat I'd li=
ke one updated proposal for this, intended for discussion ready for circula=
tion on the LEWG reflector by this Friday.</div><div dir=3D"auto"><br></div=
><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Tue, Oct 23, 2018, 1:59=
PM 'David Krauss' via ISO C++ Standard - Future Proposals <<a h=
ref=3D"mailto:std-proposals@isocpp.org" target=3D"_blank">std-proposals@iso=
cpp.org</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"=
margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style=
=3D"word-wrap:break-word">Hi Ryan, all,<div><br></div><div>Thanks for your =
support! I=E2=80=99m not an active user of C++ and I won=E2=80=99t be atten=
ding the next conference, but anyone can certainly still ping me.</div><div=
><br></div><div>Feel free to carry over the P0288 number. The main work to =
align the P0288 draft with your proposal would be rebasing the standardese =
onto the IS, from the current basis of P0045. Most of this can be done by r=
ecovering the text from P0288R0.</div><div><br></div><div>The rationale for=
P0288R1 depending on P0045 was that the shallow-const issue was spreading =
to this new class as a virus, so the fix in P0045 should be applied first t=
o contain the damage. However, two years have passed with less interest in =
P0045 (or another deep-const fix; adding deep const does not imply all of P=
0045). The fixed, dependent version P0288R1 was never presented =E2=80=94 s=
everal volunteers have come forward but the extra complication has been a h=
indrance.</div><div><br></div><div>We might focus now on building LEWG cons=
ensus on the order of dependencies. We=E2=80=99ve missed 2018 and there=E2=
=80=99s still plenty of time before Kona 2019. If some committee members ar=
e serious about deep const as a hard requirement, then they have ample oppo=
rtunity to support P0045 or to invent another solution. Otherwise, everyone=
should be able to agree on a standalone <font face=3D"Courier">unique_func=
tion</font>.</div><div><br></div><div><span class=3D"m_-2768636512439875246=
m_-1270531741872738342Apple-tab-span" style=3D"white-space:pre-wrap"> </spa=
n>- Best,</div><div><span class=3D"m_-2768636512439875246m_-127053174187273=
8342Apple-tab-span" style=3D"white-space:pre-wrap"> </span>David</div><div>=
<br></div><div><br><div><blockquote type=3D"cite"><div>On 2018=E2=80=9310=
=E2=80=9323, at 7:35 PM, Brian Budge <<a href=3D"mailto:bbudge@fb.com" r=
el=3D"noreferrer" target=3D"_blank">bbudge@fb.com</a>> wrote:</div><br c=
lass=3D"m_-2768636512439875246m_-1270531741872738342Apple-interchange-newli=
ne"><div>
<div>
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
David suggested to reach out to Jeffrey Yasskin on LEWG to loop him into th=
e discussion.<br>
<br>
</div>
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
Get <a href=3D"https://aka.ms/ghei36" rel=3D"noreferrer" target=3D"_blank">=
Outlook for Android</a></div>
<br>
</div>
<hr style=3D"display:inline-block;width:98%">
<div id=3D"m_-2768636512439875246m_-1270531741872738342divRplyFwdMsg" dir=
=3D"ltr"><font face=3D"Calibri, sans-serif" style=3D"font-size:11pt"><b>Fro=
m:</b> Lee Howes <<a href=3D"mailto:xrikcus@gmail.com" rel=3D"noreferrer=
" target=3D"_blank">xrikcus@gmail.com</a>><br>
<b>Sent:</b> Tuesday, October 23, 2018 9:57:09 AM<br>
<b>To:</b> <a href=3D"mailto:std-proposals@isocpp.org" rel=3D"noreferrer" t=
arget=3D"_blank">std-proposals@isocpp.org</a><br>
<b>Cc:</b> Brian Budge<br>
<b>Subject:</b> Re: [std-proposals] The need for std::unique_function</font=
>
<div>=C2=A0</div>
</div>
<div>
<div dir=3D"ltr">Well that was what I was thinking, but it's really up =
to you. I'm probably not the right person to advise on LEWG procedure s=
o I could easily be giving the wrong advice anyway.</div>
</div>
</div><div><br class=3D"m_-2768636512439875246m_-1270531741872738342webkit-=
block-placeholder"></div>
-- <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" rel=3D"nore=
ferrer" target=3D"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" rel=3D"noreferrer" 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/MW2PR1501MB2154FB67DE8B9F102CC016EEA2=
F50%40MW2PR1501MB2154.namprd15.prod.outlook.com?utm_medium=3Demail&utm_=
source=3Dfooter" rel=3D"noreferrer" target=3D"_blank">https://groups.google=
..com/a/isocpp.org/d/msgid/std-proposals/MW2PR1501MB2154FB67DE8B9F102CC016EE=
A2F50%40MW2PR1501MB2154.namprd15.prod.outlook.com</a>.<br>
</div></blockquote></div><br></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" rel=3D"nore=
ferrer" target=3D"_blank">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" rel=3D"noreferrer" 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/DF91B617-FD32-486E-A5B4-65AB33809C5B%=
40me.com?utm_medium=3Demail&utm_source=3Dfooter" rel=3D"noreferrer" tar=
get=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals=
/DF91B617-FD32-486E-A5B4-65AB33809C5B%40me.com</a>.<br>
</blockquote></div></div></div>
</blockquote></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/CAHn%2BA5MCw%3D5ebSe8zwTSd35GP03dTpvt=
Gv-X_vS4j1ujmEMyFQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHn%2BA5MCw%=
3D5ebSe8zwTSd35GP03dTpvtGv-X_vS4j1ujmEMyFQ%40mail.gmail.com</a>.<br />
--0000000000001ff3010578fc28b2--
.
Author: Bryce Adelstein Lelbach aka wash <brycelelbach@gmail.com>
Date: Thu, 25 Oct 2018 02:07:35 -0700
Raw View
--000000000000a38691057909efd0
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
On Wed, Oct 24, 2018, 9:41 AM Ryan McDougall <mcdougall.ryan@gmail.com>
wrote:
> From my point of view there are 2 issues:
> 1) Do we need std::unique_function: Yes
> 2) Do we want it to be move-only version of std::function, or should it b=
e
> improved version where
> ```std::unique_function<void() const> f;``` only admits targets with cons=
t
> callable operators?
>
I think there's legitimate debate about latter, but it should not preclude
> the former. Should I just present it as an open question?
>
Yes. I have not strong feelings here yet.
Lastly standardese. I don't speak it at all (yet). I can simply lift
> David's -- is that acceptable?
>
> To recapitulate:
> - Rename to P0288
> - Fold in P0045 as an option
> - Steal P0045 standardese
> - Ready by friday
>
> ^ This is the request?
>
Yes.
On Wed, Oct 24, 2018 at 12:00 AM Bryce Adelstein Lelbach aka wash <
> brycelelbach@gmail.com> wrote:
>
>> I would be willing to allocate time in LEWGI at San Diego to see this
>> paper, as it's a frequently requested feature.
>>
>> This comes with the caveat I'd like one updated proposal for this,
>> intended for discussion ready for circulation on the LEWG reflector by t=
his
>> Friday.
>>
>>
>> On Tue, Oct 23, 2018, 1:59 PM 'David Krauss' via ISO C++ Standard -
>> Future Proposals <std-proposals@isocpp.org> wrote:
>>
>>> Hi Ryan, all,
>>>
>>> Thanks for your support! I=E2=80=99m not an active user of C++ and I wo=
n=E2=80=99t be
>>> attending the next conference, but anyone can certainly still ping me.
>>>
>>> Feel free to carry over the P0288 number. The main work to align the
>>> P0288 draft with your proposal would be rebasing the standardese onto t=
he
>>> IS, from the current basis of P0045. Most of this can be done by recove=
ring
>>> the text from P0288R0.
>>>
>>> The rationale for P0288R1 depending on P0045 was that the shallow-const
>>> issue was spreading to this new class as a virus, so the fix in P0045
>>> should be applied first to contain the damage. However, two years have
>>> passed with less interest in P0045 (or another deep-const fix; adding d=
eep
>>> const does not imply all of P0045). The fixed, dependent version P0288R=
1
>>> was never presented =E2=80=94 several volunteers have come forward but =
the extra
>>> complication has been a hindrance.
>>>
>>> We might focus now on building LEWG consensus on the order of
>>> dependencies. We=E2=80=99ve missed 2018 and there=E2=80=99s still plent=
y of time before
>>> Kona 2019. If some committee members are serious about deep const as a =
hard
>>> requirement, then they have ample opportunity to support P0045 or to in=
vent
>>> another solution. Otherwise, everyone should be able to agree on a
>>> standalone unique_function.
>>>
>>> - Best,
>>> David
>>>
>>>
>>> On 2018=E2=80=9310=E2=80=9323, at 7:35 PM, Brian Budge <bbudge@fb.com> =
wrote:
>>>
>>> David suggested to reach out to Jeffrey Yasskin on LEWG to loop him int=
o
>>> the discussion.
>>>
>>> Get Outlook for Android <https://aka.ms/ghei36>
>>>
>>> ------------------------------
>>> *From:* Lee Howes <xrikcus@gmail.com>
>>> *Sent:* Tuesday, October 23, 2018 9:57:09 AM
>>> *To:* std-proposals@isocpp.org
>>> *Cc:* Brian Budge
>>> *Subject:* Re: [std-proposals] The need for std::unique_function
>>>
>>> Well that was what I was thinking, but it's really up to you. I'm
>>> probably not the right person to advise on LEWG procedure so I could ea=
sily
>>> be giving the wrong advice anyway.
>>>
>>> --
>>> 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/MW2PR1501M=
B2154FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.com
>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/MW2PR1501=
MB2154FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.com=
?utm_medium=3Demail&utm_source=3Dfooter>
>>> .
>>>
>>>
>>> --
>>> 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/DF91B617-F=
D32-486E-A5B4-65AB33809C5B%40me.com
>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/DF91B617-=
FD32-486E-A5B4-65AB33809C5B%40me.com?utm_medium=3Demail&utm_source=3Dfooter=
>
>>> .
>>>
>>
--=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/CAP3wax__0hayf2KweVWRusT_xEquEkVCXRxt13tXutsZ0%2=
Baymw%40mail.gmail.com.
--000000000000a38691057909efd0
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"auto"><div><br><br><div class=3D"gmail_quote"><div dir=3D"ltr">=
On Wed, Oct 24, 2018, 9:41 AM Ryan McDougall <<a href=3D"mailto:mcdougal=
l.ryan@gmail.com">mcdougall.ryan@gmail.com</a>> wrote:<br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div dir=3D"ltr">From my point of view there are 2 i=
ssues:<div>1) Do we need std::unique_function: Yes<br>2) Do we want it to b=
e move-only version of std::function, or should it be improved version wher=
e<br>```std::unique_function<void() const> f;``` only admits targets =
with const callable operators?<br></div></div></blockquote></div></div><div=
dir=3D"auto"><br></div><div dir=3D"auto"><br></div><div dir=3D"auto"><br><=
/div><div dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D"gmail_quot=
e"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>I think there's=
legitimate debate about latter, but it should not preclude the former. Sho=
uld I just present it as an open question?</div></div></blockquote></div></=
div><div dir=3D"auto"><br></div><div dir=3D"auto">Yes. I have not strong fe=
elings here yet.</div><div dir=3D"auto"></div><div dir=3D"auto"><br></div><=
div dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D"gmail_quote"><bl=
ockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #=
ccc solid;padding-left:1ex"><div dir=3D"ltr"><div>Lastly standardese. I don=
't speak it at all (yet). I can simply lift David's -- is that acce=
ptable?<br><br>To recapitulate:<br>- Rename to P0288<br>- Fold in P0045 as =
an option<br>- Steal P0045 standardese<br>- Ready by friday<br><br>^ This i=
s the request?</div></div></blockquote></div></div><div dir=3D"auto"><br></=
div><div dir=3D"auto">Yes.</div><div dir=3D"auto"><br></div><div dir=3D"aut=
o"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" style=3D"ma=
rgin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class=3D"=
gmail_quote"><div dir=3D"ltr">On Wed, Oct 24, 2018 at 12:00 AM Bryce Adelst=
ein Lelbach aka wash <<a href=3D"mailto:brycelelbach@gmail.com" target=
=3D"_blank" rel=3D"noreferrer">brycelelbach@gmail.com</a>> wrote:<br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div dir=3D"auto"><div>I would be willing=
to allocate time in LEWGI at San Diego to see this paper, as it's a fr=
equently requested feature.<div dir=3D"auto"><br></div><div dir=3D"auto">Th=
is comes with the caveat I'd like one updated proposal for this, intend=
ed for discussion ready for circulation on the LEWG reflector by this Frida=
y.</div><div dir=3D"auto"><br></div><br><div class=3D"gmail_quote"><div dir=
=3D"ltr">On Tue, Oct 23, 2018, 1:59 PM 'David Krauss' via ISO C++ S=
tandard - Future Proposals <<a href=3D"mailto:std-proposals@isocpp.org" =
target=3D"_blank" rel=3D"noreferrer">std-proposals@isocpp.org</a>> wrote=
:<br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;bor=
der-left:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-wor=
d">Hi Ryan, all,<div><br></div><div>Thanks for your support! I=E2=80=99m no=
t an active user of C++ and I won=E2=80=99t be attending the next conferenc=
e, but anyone can certainly still ping me.</div><div><br></div><div>Feel fr=
ee to carry over the P0288 number. The main work to align the P0288 draft w=
ith your proposal would be rebasing the standardese onto the IS, from the c=
urrent basis of P0045. Most of this can be done by recovering the text from=
P0288R0.</div><div><br></div><div>The rationale for P0288R1 depending on P=
0045 was that the shallow-const issue was spreading to this new class as a =
virus, so the fix in P0045 should be applied first to contain the damage. H=
owever, two years have passed with less interest in P0045 (or another deep-=
const fix; adding deep const does not imply all of P0045). The fixed, depen=
dent version P0288R1 was never presented =E2=80=94 several volunteers have =
come forward but the extra complication has been a hindrance.</div><div><br=
></div><div>We might focus now on building LEWG consensus on the order of d=
ependencies. We=E2=80=99ve missed 2018 and there=E2=80=99s still plenty of =
time before Kona 2019. If some committee members are serious about deep con=
st as a hard requirement, then they have ample opportunity to support P0045=
or to invent another solution. Otherwise, everyone should be able to agree=
on a standalone <font face=3D"Courier">unique_function</font>.</div><div><=
br></div><div><span class=3D"m_2723891306143681030m_-2768636512439875246m_-=
1270531741872738342Apple-tab-span" style=3D"white-space:pre-wrap"> </span>-=
Best,</div><div><span class=3D"m_2723891306143681030m_-2768636512439875246=
m_-1270531741872738342Apple-tab-span" style=3D"white-space:pre-wrap"> </spa=
n>David</div><div><br></div><div><br><div><blockquote type=3D"cite"><div>On=
2018=E2=80=9310=E2=80=9323, at 7:35 PM, Brian Budge <<a href=3D"mailto:=
bbudge@fb.com" rel=3D"noreferrer noreferrer" target=3D"_blank">bbudge@fb.co=
m</a>> wrote:</div><br class=3D"m_2723891306143681030m_-2768636512439875=
246m_-1270531741872738342Apple-interchange-newline"><div>
<div>
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
David suggested to reach out to Jeffrey Yasskin on LEWG to loop him into th=
e discussion.<br>
<br>
</div>
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
Get <a href=3D"https://aka.ms/ghei36" rel=3D"noreferrer noreferrer" target=
=3D"_blank">Outlook for Android</a></div>
<br>
</div>
<hr style=3D"display:inline-block;width:98%">
<div id=3D"m_2723891306143681030m_-2768636512439875246m_-127053174187273834=
2divRplyFwdMsg" dir=3D"ltr"><font face=3D"Calibri, sans-serif" style=3D"fon=
t-size:11pt"><b>From:</b> Lee Howes <<a href=3D"mailto:xrikcus@gmail.com=
" rel=3D"noreferrer noreferrer" target=3D"_blank">xrikcus@gmail.com</a>>=
<br>
<b>Sent:</b> Tuesday, October 23, 2018 9:57:09 AM<br>
<b>To:</b> <a href=3D"mailto:std-proposals@isocpp.org" rel=3D"noreferrer no=
referrer" target=3D"_blank">std-proposals@isocpp.org</a><br>
<b>Cc:</b> Brian Budge<br>
<b>Subject:</b> Re: [std-proposals] The need for std::unique_function</font=
>
<div>=C2=A0</div>
</div>
<div>
<div dir=3D"ltr">Well that was what I was thinking, but it's really up =
to you. I'm probably not the right person to advise on LEWG procedure s=
o I could easily be giving the wrong advice anyway.</div>
</div>
</div><div><br class=3D"m_2723891306143681030m_-2768636512439875246m_-12705=
31741872738342webkit-block-placeholder"></div>
-- <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" rel=3D"nore=
ferrer noreferrer" target=3D"_blank">std-proposals+unsubscribe@isocpp.org</=
a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" rel=3D"noreferrer noreferrer" 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/MW2PR1501MB2154FB67DE8B9F102CC016EEA2=
F50%40MW2PR1501MB2154.namprd15.prod.outlook.com?utm_medium=3Demail&utm_=
source=3Dfooter" rel=3D"noreferrer noreferrer" target=3D"_blank">https://gr=
oups.google.com/a/isocpp.org/d/msgid/std-proposals/MW2PR1501MB2154FB67DE8B9=
F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.com</a>.<br>
</div></blockquote></div><br></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" rel=3D"nore=
ferrer noreferrer" target=3D"_blank">std-proposals+unsubscribe@isocpp.org</=
a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" rel=3D"noreferrer noreferrer" 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/DF91B617-FD32-486E-A5B4-65AB33809C5B%=
40me.com?utm_medium=3Demail&utm_source=3Dfooter" rel=3D"noreferrer nore=
ferrer" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/DF91B617-FD32-486E-A5B4-65AB33809C5B%40me.com</a>.<br>
</blockquote></div></div></div>
</blockquote></div>
</blockquote></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/CAP3wax__0hayf2KweVWRusT_xEquEkVCXRxt=
13tXutsZ0%2Baymw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter">h=
ttps://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAP3wax__0hayf2=
KweVWRusT_xEquEkVCXRxt13tXutsZ0%2Baymw%40mail.gmail.com</a>.<br />
--000000000000a38691057909efd0--
.
Author: Ryan McDougall <mcdougall.ryan@gmail.com>
Date: Thu, 25 Oct 2018 09:27:09 -0700
Raw View
--000000000000c96676057910130d
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Ok I still don't have access to the mailing lists and am not sure how long
that takes. I assume you can post in my stead until then?
On Thu, Oct 25, 2018 at 2:07 AM Bryce Adelstein Lelbach aka wash <
brycelelbach@gmail.com> wrote:
>
>
> On Wed, Oct 24, 2018, 9:41 AM Ryan McDougall <mcdougall.ryan@gmail.com>
> wrote:
>
>> From my point of view there are 2 issues:
>> 1) Do we need std::unique_function: Yes
>> 2) Do we want it to be move-only version of std::function, or should it
>> be improved version where
>> ```std::unique_function<void() const> f;``` only admits targets with
>> const callable operators?
>>
>
>
>
>
> I think there's legitimate debate about latter, but it should not preclud=
e
>> the former. Should I just present it as an open question?
>>
>
> Yes. I have not strong feelings here yet.
>
>
> Lastly standardese. I don't speak it at all (yet). I can simply lift
>> David's -- is that acceptable?
>>
>> To recapitulate:
>> - Rename to P0288
>> - Fold in P0045 as an option
>> - Steal P0045 standardese
>> - Ready by friday
>>
>> ^ This is the request?
>>
>
> Yes.
>
> On Wed, Oct 24, 2018 at 12:00 AM Bryce Adelstein Lelbach aka wash <
>> brycelelbach@gmail.com> wrote:
>>
>>> I would be willing to allocate time in LEWGI at San Diego to see this
>>> paper, as it's a frequently requested feature.
>>>
>>> This comes with the caveat I'd like one updated proposal for this,
>>> intended for discussion ready for circulation on the LEWG reflector by =
this
>>> Friday.
>>>
>>>
>>> On Tue, Oct 23, 2018, 1:59 PM 'David Krauss' via ISO C++ Standard -
>>> Future Proposals <std-proposals@isocpp.org> wrote:
>>>
>>>> Hi Ryan, all,
>>>>
>>>> Thanks for your support! I=E2=80=99m not an active user of C++ and I w=
on=E2=80=99t be
>>>> attending the next conference, but anyone can certainly still ping me.
>>>>
>>>> Feel free to carry over the P0288 number. The main work to align the
>>>> P0288 draft with your proposal would be rebasing the standardese onto =
the
>>>> IS, from the current basis of P0045. Most of this can be done by recov=
ering
>>>> the text from P0288R0.
>>>>
>>>> The rationale for P0288R1 depending on P0045 was that the shallow-cons=
t
>>>> issue was spreading to this new class as a virus, so the fix in P0045
>>>> should be applied first to contain the damage. However, two years have
>>>> passed with less interest in P0045 (or another deep-const fix; adding =
deep
>>>> const does not imply all of P0045). The fixed, dependent version P0288=
R1
>>>> was never presented =E2=80=94 several volunteers have come forward but=
the extra
>>>> complication has been a hindrance.
>>>>
>>>> We might focus now on building LEWG consensus on the order of
>>>> dependencies. We=E2=80=99ve missed 2018 and there=E2=80=99s still plen=
ty of time before
>>>> Kona 2019. If some committee members are serious about deep const as a=
hard
>>>> requirement, then they have ample opportunity to support P0045 or to i=
nvent
>>>> another solution. Otherwise, everyone should be able to agree on a
>>>> standalone unique_function.
>>>>
>>>> - Best,
>>>> David
>>>>
>>>>
>>>> On 2018=E2=80=9310=E2=80=9323, at 7:35 PM, Brian Budge <bbudge@fb.com>=
wrote:
>>>>
>>>> David suggested to reach out to Jeffrey Yasskin on LEWG to loop him
>>>> into the discussion.
>>>>
>>>> Get Outlook for Android <https://aka.ms/ghei36>
>>>>
>>>> ------------------------------
>>>> *From:* Lee Howes <xrikcus@gmail.com>
>>>> *Sent:* Tuesday, October 23, 2018 9:57:09 AM
>>>> *To:* std-proposals@isocpp.org
>>>> *Cc:* Brian Budge
>>>> *Subject:* Re: [std-proposals] The need for std::unique_function
>>>>
>>>> Well that was what I was thinking, but it's really up to you. I'm
>>>> probably not the right person to advise on LEWG procedure so I could e=
asily
>>>> be giving the wrong advice anyway.
>>>>
>>>> --
>>>> 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/MW2PR1501=
MB2154FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.com
>>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/MW2PR150=
1MB2154FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.co=
m?utm_medium=3Demail&utm_source=3Dfooter>
>>>> .
>>>>
>>>>
>>>> --
>>>> 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/DF91B617-=
FD32-486E-A5B4-65AB33809C5B%40me.com
>>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/DF91B617=
-FD32-486E-A5B4-65AB33809C5B%40me.com?utm_medium=3Demail&utm_source=3Dfoote=
r>
>>>> .
>>>>
>>> --
> 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/CAP3wax__0ha=
yf2KweVWRusT_xEquEkVCXRxt13tXutsZ0%2Baymw%40mail.gmail.com
> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAP3wax__0h=
ayf2KweVWRusT_xEquEkVCXRxt13tXutsZ0%2Baymw%40mail.gmail.com?utm_medium=3Dem=
ail&utm_source=3Dfooter>
> .
>
--=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/CAHn%2BA5Nb-cB4%3D%3Ds8aRO978Ndt%3DNDRuJPmSnXKCG=
mmrhcx8z1GA%40mail.gmail.com.
--000000000000c96676057910130d
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Ok I still don't have access to the mailing lists and =
am not sure how long that takes. I assume you can post in my stead until th=
en?</div><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, Oct 25, 20=
18 at 2:07 AM Bryce Adelstein Lelbach aka wash <<a href=3D"mailto:brycel=
elbach@gmail.com">brycelelbach@gmail.com</a>> wrote:<br></div><blockquot=
e class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc sol=
id;padding-left:1ex"><div dir=3D"auto"><div><br><br><div class=3D"gmail_quo=
te"><div dir=3D"ltr">On Wed, Oct 24, 2018, 9:41 AM Ryan McDougall <<a hr=
ef=3D"mailto:mcdougall.ryan@gmail.com" target=3D"_blank">mcdougall.ryan@gma=
il.com</a>> wrote:<br></div><blockquote class=3D"gmail_quote" style=3D"m=
argin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir=3D"l=
tr">From my point of view there are 2 issues:<div>1) Do we need std::unique=
_function: Yes<br>2) Do we want it to be move-only version of std::function=
, or should it be improved version where<br>```std::unique_function<void=
() const> f;``` only admits targets with const callable operators?<br></=
div></div></blockquote></div></div><div dir=3D"auto"><br></div><div dir=3D"=
auto"><br></div><div dir=3D"auto"><br></div><div dir=3D"auto"><br></div><di=
v dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote"=
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><d=
iv dir=3D"ltr"><div>I think there's legitimate debate about latter, but=
it should not preclude the former. Should I just present it as an open que=
stion?</div></div></blockquote></div></div><div dir=3D"auto"><br></div><div=
dir=3D"auto">Yes. I have not strong feelings here yet.</div><div dir=3D"au=
to"></div><div dir=3D"auto"><br></div><div dir=3D"auto"><br></div><div dir=
=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quote" styl=
e=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div di=
r=3D"ltr"><div>Lastly standardese. I don't speak it at all (yet). I can=
simply lift David's -- is that acceptable?<br><br>To recapitulate:<br>=
- Rename to P0288<br>- Fold in P0045 as an option<br>- Steal P0045 standard=
ese<br>- Ready by friday<br><br>^ This is the request?</div></div></blockqu=
ote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">Yes.</div><di=
v dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D"gmail_quote"><bloc=
kquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #cc=
c solid;padding-left:1ex"><div class=3D"gmail_quote"><div dir=3D"ltr">On We=
d, Oct 24, 2018 at 12:00 AM Bryce Adelstein Lelbach aka wash <<a href=3D=
"mailto:brycelelbach@gmail.com" rel=3D"noreferrer" target=3D"_blank">brycel=
elbach@gmail.com</a>> wrote:<br></div><blockquote class=3D"gmail_quote" =
style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><di=
v dir=3D"auto"><div>I would be willing to allocate time in LEWGI at San Die=
go to see this paper, as it's a frequently requested feature.<div dir=
=3D"auto"><br></div><div dir=3D"auto">This comes with the caveat I'd li=
ke one updated proposal for this, intended for discussion ready for circula=
tion on the LEWG reflector by this Friday.</div><div dir=3D"auto"><br></div=
><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Tue, Oct 23, 2018, 1:59=
PM 'David Krauss' via ISO C++ Standard - Future Proposals <<a h=
ref=3D"mailto:std-proposals@isocpp.org" rel=3D"noreferrer" target=3D"_blank=
">std-proposals@isocpp.org</a>> wrote:<br></div><blockquote class=3D"gma=
il_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-lef=
t:1ex"><div style=3D"word-wrap:break-word">Hi Ryan, all,<div><br></div><div=
>Thanks for your support! I=E2=80=99m not an active user of C++ and I won=
=E2=80=99t be attending the next conference, but anyone can certainly still=
ping me.</div><div><br></div><div>Feel free to carry over the P0288 number=
.. The main work to align the P0288 draft with your proposal would be rebasi=
ng the standardese onto the IS, from the current basis of P0045. Most of th=
is can be done by recovering the text from P0288R0.</div><div><br></div><di=
v>The rationale for P0288R1 depending on P0045 was that the shallow-const i=
ssue was spreading to this new class as a virus, so the fix in P0045 should=
be applied first to contain the damage. However, two years have passed wit=
h less interest in P0045 (or another deep-const fix; adding deep const does=
not imply all of P0045). The fixed, dependent version P0288R1 was never pr=
esented =E2=80=94 several volunteers have come forward but the extra compli=
cation has been a hindrance.</div><div><br></div><div>We might focus now on=
building LEWG consensus on the order of dependencies. We=E2=80=99ve missed=
2018 and there=E2=80=99s still plenty of time before Kona 2019. If some co=
mmittee members are serious about deep const as a hard requirement, then th=
ey have ample opportunity to support P0045 or to invent another solution. O=
therwise, everyone should be able to agree on a standalone <font face=3D"Co=
urier">unique_function</font>.</div><div><br></div><div><span class=3D"m_79=
22344984094274404m_2723891306143681030m_-2768636512439875246m_-127053174187=
2738342Apple-tab-span" style=3D"white-space:pre-wrap"> </span>- Best,</div>=
<div><span class=3D"m_7922344984094274404m_2723891306143681030m_-2768636512=
439875246m_-1270531741872738342Apple-tab-span" style=3D"white-space:pre-wra=
p"> </span>David</div><div><br></div><div><br><div><blockquote type=3D"cite=
"><div>On 2018=E2=80=9310=E2=80=9323, at 7:35 PM, Brian Budge <<a href=
=3D"mailto:bbudge@fb.com" rel=3D"noreferrer noreferrer" target=3D"_blank">b=
budge@fb.com</a>> wrote:</div><br class=3D"m_7922344984094274404m_272389=
1306143681030m_-2768636512439875246m_-1270531741872738342Apple-interchange-=
newline"><div>
<div>
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
David suggested to reach out to Jeffrey Yasskin on LEWG to loop him into th=
e discussion.<br>
<br>
</div>
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
Get <a href=3D"https://aka.ms/ghei36" rel=3D"noreferrer noreferrer" target=
=3D"_blank">Outlook for Android</a></div>
<br>
</div>
<hr style=3D"display:inline-block;width:98%">
<div id=3D"m_7922344984094274404m_2723891306143681030m_-2768636512439875246=
m_-1270531741872738342divRplyFwdMsg" dir=3D"ltr"><font face=3D"Calibri, san=
s-serif" style=3D"font-size:11pt"><b>From:</b> Lee Howes <<a href=3D"mai=
lto:xrikcus@gmail.com" rel=3D"noreferrer noreferrer" target=3D"_blank">xrik=
cus@gmail.com</a>><br>
<b>Sent:</b> Tuesday, October 23, 2018 9:57:09 AM<br>
<b>To:</b> <a href=3D"mailto:std-proposals@isocpp.org" rel=3D"noreferrer no=
referrer" target=3D"_blank">std-proposals@isocpp.org</a><br>
<b>Cc:</b> Brian Budge<br>
<b>Subject:</b> Re: [std-proposals] The need for std::unique_function</font=
>
<div>=C2=A0</div>
</div>
<div>
<div dir=3D"ltr">Well that was what I was thinking, but it's really up =
to you. I'm probably not the right person to advise on LEWG procedure s=
o I could easily be giving the wrong advice anyway.</div>
</div>
</div><div><br class=3D"m_7922344984094274404m_2723891306143681030m_-276863=
6512439875246m_-1270531741872738342webkit-block-placeholder"></div>
-- <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" rel=3D"nore=
ferrer noreferrer" target=3D"_blank">std-proposals+unsubscribe@isocpp.org</=
a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" rel=3D"noreferrer noreferrer" 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/MW2PR1501MB2154FB67DE8B9F102CC016EEA2=
F50%40MW2PR1501MB2154.namprd15.prod.outlook.com?utm_medium=3Demail&utm_=
source=3Dfooter" rel=3D"noreferrer noreferrer" target=3D"_blank">https://gr=
oups.google.com/a/isocpp.org/d/msgid/std-proposals/MW2PR1501MB2154FB67DE8B9=
F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.com</a>.<br>
</div></blockquote></div><br></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" rel=3D"nore=
ferrer noreferrer" target=3D"_blank">std-proposals+unsubscribe@isocpp.org</=
a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" rel=3D"noreferrer noreferrer" 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/DF91B617-FD32-486E-A5B4-65AB33809C5B%=
40me.com?utm_medium=3Demail&utm_source=3Dfooter" rel=3D"noreferrer nore=
ferrer" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/DF91B617-FD32-486E-A5B4-65AB33809C5B%40me.com</a>.<br>
</blockquote></div></div></div>
</blockquote></div>
</blockquote></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" target=3D"_=
blank">std-proposals+unsubscribe@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/CAP3wax__0hayf2KweVWRusT_xEquEkVCXRxt=
13tXutsZ0%2Baymw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-pro=
posals/CAP3wax__0hayf2KweVWRusT_xEquEkVCXRxt13tXutsZ0%2Baymw%40mail.gmail.c=
om</a>.<br>
</blockquote></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/CAHn%2BA5Nb-cB4%3D%3Ds8aRO978Ndt%3DND=
RuJPmSnXKCGmmrhcx8z1GA%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHn%2BA5=
Nb-cB4%3D%3Ds8aRO978Ndt%3DNDRuJPmSnXKCGmmrhcx8z1GA%40mail.gmail.com</a>.<br=
/>
--000000000000c96676057910130d--
.
Author: Ryan McDougall <mcdougall.ryan@gmail.com>
Date: Thu, 25 Oct 2018 10:45:55 -0700
Raw View
--00000000000080db800579112db7
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Updated version for those following at home
https://docs.google.com/document/d/1fiaaqTubxw-EUeveejcTAubAaMQYQZ19Qt2VmHr=
bbok/edit?usp=3Dsharing
On Thu, Oct 25, 2018 at 9:27 AM Ryan McDougall <mcdougall.ryan@gmail.com>
wrote:
> Ok I still don't have access to the mailing lists and am not sure how lon=
g
> that takes. I assume you can post in my stead until then?
>
> On Thu, Oct 25, 2018 at 2:07 AM Bryce Adelstein Lelbach aka wash <
> brycelelbach@gmail.com> wrote:
>
>>
>>
>> On Wed, Oct 24, 2018, 9:41 AM Ryan McDougall <mcdougall.ryan@gmail.com>
>> wrote:
>>
>>> From my point of view there are 2 issues:
>>> 1) Do we need std::unique_function: Yes
>>> 2) Do we want it to be move-only version of std::function, or should it
>>> be improved version where
>>> ```std::unique_function<void() const> f;``` only admits targets with
>>> const callable operators?
>>>
>>
>>
>>
>>
>> I think there's legitimate debate about latter, but it should not
>>> preclude the former. Should I just present it as an open question?
>>>
>>
>> Yes. I have not strong feelings here yet.
>>
>>
>> Lastly standardese. I don't speak it at all (yet). I can simply lift
>>> David's -- is that acceptable?
>>>
>>> To recapitulate:
>>> - Rename to P0288
>>> - Fold in P0045 as an option
>>> - Steal P0045 standardese
>>> - Ready by friday
>>>
>>> ^ This is the request?
>>>
>>
>> Yes.
>>
>> On Wed, Oct 24, 2018 at 12:00 AM Bryce Adelstein Lelbach aka wash <
>>> brycelelbach@gmail.com> wrote:
>>>
>>>> I would be willing to allocate time in LEWGI at San Diego to see this
>>>> paper, as it's a frequently requested feature.
>>>>
>>>> This comes with the caveat I'd like one updated proposal for this,
>>>> intended for discussion ready for circulation on the LEWG reflector by=
this
>>>> Friday.
>>>>
>>>>
>>>> On Tue, Oct 23, 2018, 1:59 PM 'David Krauss' via ISO C++ Standard -
>>>> Future Proposals <std-proposals@isocpp.org> wrote:
>>>>
>>>>> Hi Ryan, all,
>>>>>
>>>>> Thanks for your support! I=E2=80=99m not an active user of C++ and I =
won=E2=80=99t be
>>>>> attending the next conference, but anyone can certainly still ping me=
..
>>>>>
>>>>> Feel free to carry over the P0288 number. The main work to align the
>>>>> P0288 draft with your proposal would be rebasing the standardese onto=
the
>>>>> IS, from the current basis of P0045. Most of this can be done by reco=
vering
>>>>> the text from P0288R0.
>>>>>
>>>>> The rationale for P0288R1 depending on P0045 was that the
>>>>> shallow-const issue was spreading to this new class as a virus, so th=
e fix
>>>>> in P0045 should be applied first to contain the damage. However, two =
years
>>>>> have passed with less interest in P0045 (or another deep-const fix; a=
dding
>>>>> deep const does not imply all of P0045). The fixed, dependent version
>>>>> P0288R1 was never presented =E2=80=94 several volunteers have come fo=
rward but the
>>>>> extra complication has been a hindrance.
>>>>>
>>>>> We might focus now on building LEWG consensus on the order of
>>>>> dependencies. We=E2=80=99ve missed 2018 and there=E2=80=99s still ple=
nty of time before
>>>>> Kona 2019. If some committee members are serious about deep const as =
a hard
>>>>> requirement, then they have ample opportunity to support P0045 or to =
invent
>>>>> another solution. Otherwise, everyone should be able to agree on a
>>>>> standalone unique_function.
>>>>>
>>>>> - Best,
>>>>> David
>>>>>
>>>>>
>>>>> On 2018=E2=80=9310=E2=80=9323, at 7:35 PM, Brian Budge <bbudge@fb.com=
> wrote:
>>>>>
>>>>> David suggested to reach out to Jeffrey Yasskin on LEWG to loop him
>>>>> into the discussion.
>>>>>
>>>>> Get Outlook for Android <https://aka.ms/ghei36>
>>>>>
>>>>> ------------------------------
>>>>> *From:* Lee Howes <xrikcus@gmail.com>
>>>>> *Sent:* Tuesday, October 23, 2018 9:57:09 AM
>>>>> *To:* std-proposals@isocpp.org
>>>>> *Cc:* Brian Budge
>>>>> *Subject:* Re: [std-proposals] The need for std::unique_function
>>>>>
>>>>> Well that was what I was thinking, but it's really up to you. I'm
>>>>> probably not the right person to advise on LEWG procedure so I could =
easily
>>>>> be giving the wrong advice anyway.
>>>>>
>>>>> --
>>>>> 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, sen=
d
>>>>> 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/MW2PR150=
1MB2154FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.co=
m
>>>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/MW2PR15=
01MB2154FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.c=
om?utm_medium=3Demail&utm_source=3Dfooter>
>>>>> .
>>>>>
>>>>>
>>>>> --
>>>>> 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, sen=
d
>>>>> 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/DF91B617=
-FD32-486E-A5B4-65AB33809C5B%40me.com
>>>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/DF91B61=
7-FD32-486E-A5B4-65AB33809C5B%40me.com?utm_medium=3Demail&utm_source=3Dfoot=
er>
>>>>> .
>>>>>
>>>> --
>> You received this message because you are subscribed to the Google Group=
s
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> 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/CAP3wax__0h=
ayf2KweVWRusT_xEquEkVCXRxt13tXutsZ0%2Baymw%40mail.gmail.com
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAP3wax__0=
hayf2KweVWRusT_xEquEkVCXRxt13tXutsZ0%2Baymw%40mail.gmail.com?utm_medium=3De=
mail&utm_source=3Dfooter>
>> .
>>
>
--=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/CAHn%2BA5P_Qcjx3RmobVoZes3VsRvXF5g6pYxUKfd1ru70D=
Jq_%3DQ%40mail.gmail.com.
--00000000000080db800579112db7
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr"><div dir=3D"ltr">Updated version for those following at ho=
me <a href=3D"https://docs.google.com/document/d/1fiaaqTubxw-EUeveejcTAubAa=
MQYQZ19Qt2VmHrbbok/edit?usp=3Dsharing">https://docs.google.com/document/d/1=
fiaaqTubxw-EUeveejcTAubAaMQYQZ19Qt2VmHrbbok/edit?usp=3Dsharing</a></div></d=
iv><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, Oct 25, 2018 at =
9:27 AM Ryan McDougall <<a href=3D"mailto:mcdougall.ryan@gmail.com">mcdo=
ugall.ryan@gmail.com</a>> wrote:<br></div><blockquote class=3D"gmail_quo=
te" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"=
><div dir=3D"ltr">Ok I still don't have access to the mailing lists and=
am not sure how long that takes. I assume you can post in my stead until t=
hen?</div><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Thu, Oct 25, 2=
018 at 2:07 AM Bryce Adelstein Lelbach aka wash <<a href=3D"mailto:bryce=
lelbach@gmail.com" target=3D"_blank">brycelelbach@gmail.com</a>> wrote:<=
br></div><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;borde=
r-left:1px #ccc solid;padding-left:1ex"><div dir=3D"auto"><div><br><br><div=
class=3D"gmail_quote"><div dir=3D"ltr">On Wed, Oct 24, 2018, 9:41 AM Ryan =
McDougall <<a href=3D"mailto:mcdougall.ryan@gmail.com" target=3D"_blank"=
>mcdougall.ryan@gmail.com</a>> wrote:<br></div><blockquote class=3D"gmai=
l_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left=
:1ex"><div dir=3D"ltr">From my point of view there are 2 issues:<div>1) Do =
we need std::unique_function: Yes<br>2) Do we want it to be move-only versi=
on of std::function, or should it be improved version where<br>```std::uniq=
ue_function<void() const> f;``` only admits targets with const callab=
le operators?<br></div></div></blockquote></div></div><div dir=3D"auto"><br=
></div><div dir=3D"auto"><br></div><div dir=3D"auto"><br></div><div dir=3D"=
auto"><br></div><div dir=3D"auto"><div class=3D"gmail_quote"><blockquote cl=
ass=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;p=
adding-left:1ex"><div dir=3D"ltr"><div>I think there's legitimate debat=
e about latter, but it should not preclude the former. Should I just presen=
t it as an open question?</div></div></blockquote></div></div><div dir=3D"a=
uto"><br></div><div dir=3D"auto">Yes. I have not strong feelings here yet.<=
/div><div dir=3D"auto"></div><div dir=3D"auto"><br></div><div dir=3D"auto">=
<br></div><div dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D=
"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding=
-left:1ex"><div dir=3D"ltr"><div>Lastly standardese. I don't speak it a=
t all (yet). I can simply lift David's -- is that acceptable?<br><br>To=
recapitulate:<br>- Rename to P0288<br>- Fold in P0045 as an option<br>- St=
eal P0045 standardese<br>- Ready by friday<br><br>^ This is the request?</d=
iv></div></blockquote></div></div><div dir=3D"auto"><br></div><div dir=3D"a=
uto">Yes.</div><div dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D"=
gmail_quote"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;b=
order-left:1px #ccc solid;padding-left:1ex"><div class=3D"gmail_quote"><div=
dir=3D"ltr">On Wed, Oct 24, 2018 at 12:00 AM Bryce Adelstein Lelbach aka w=
ash <<a href=3D"mailto:brycelelbach@gmail.com" rel=3D"noreferrer" target=
=3D"_blank">brycelelbach@gmail.com</a>> wrote:<br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"auto"><div>I would be willing to allocate time i=
n LEWGI at San Diego to see this paper, as it's a frequently requested =
feature.<div dir=3D"auto"><br></div><div dir=3D"auto">This comes with the c=
aveat I'd like one updated proposal for this, intended for discussion r=
eady for circulation on the LEWG reflector by this Friday.</div><div dir=3D=
"auto"><br></div><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Tue, Oc=
t 23, 2018, 1:59 PM 'David Krauss' via ISO C++ Standard - Future Pr=
oposals <<a href=3D"mailto:std-proposals@isocpp.org" rel=3D"noreferrer" =
target=3D"_blank">std-proposals@isocpp.org</a>> wrote:<br></div><blockqu=
ote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc s=
olid;padding-left:1ex"><div style=3D"word-wrap:break-word">Hi Ryan, all,<di=
v><br></div><div>Thanks for your support! I=E2=80=99m not an active user of=
C++ and I won=E2=80=99t be attending the next conference, but anyone can c=
ertainly still ping me.</div><div><br></div><div>Feel free to carry over th=
e P0288 number. The main work to align the P0288 draft with your proposal w=
ould be rebasing the standardese onto the IS, from the current basis of P00=
45. Most of this can be done by recovering the text from P0288R0.</div><div=
><br></div><div>The rationale for P0288R1 depending on P0045 was that the s=
hallow-const issue was spreading to this new class as a virus, so the fix i=
n P0045 should be applied first to contain the damage. However, two years h=
ave passed with less interest in P0045 (or another deep-const fix; adding d=
eep const does not imply all of P0045). The fixed, dependent version P0288R=
1 was never presented =E2=80=94 several volunteers have come forward but th=
e extra complication has been a hindrance.</div><div><br></div><div>We migh=
t focus now on building LEWG consensus on the order of dependencies. We=E2=
=80=99ve missed 2018 and there=E2=80=99s still plenty of time before Kona 2=
019. If some committee members are serious about deep const as a hard requi=
rement, then they have ample opportunity to support P0045 or to invent anot=
her solution. Otherwise, everyone should be able to agree on a standalone <=
font face=3D"Courier">unique_function</font>.</div><div><br></div><div><spa=
n class=3D"m_-4133442876550725775m_7922344984094274404m_2723891306143681030=
m_-2768636512439875246m_-1270531741872738342Apple-tab-span" style=3D"white-=
space:pre-wrap"> </span>- Best,</div><div><span class=3D"m_-413344287655072=
5775m_7922344984094274404m_2723891306143681030m_-2768636512439875246m_-1270=
531741872738342Apple-tab-span" style=3D"white-space:pre-wrap"> </span>David=
</div><div><br></div><div><br><div><blockquote type=3D"cite"><div>On 2018=
=E2=80=9310=E2=80=9323, at 7:35 PM, Brian Budge <<a href=3D"mailto:bbudg=
e@fb.com" rel=3D"noreferrer noreferrer" target=3D"_blank">bbudge@fb.com</a>=
> wrote:</div><br class=3D"m_-4133442876550725775m_7922344984094274404m_=
2723891306143681030m_-2768636512439875246m_-1270531741872738342Apple-interc=
hange-newline"><div>
<div>
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
David suggested to reach out to Jeffrey Yasskin on LEWG to loop him into th=
e discussion.<br>
<br>
</div>
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
Get <a href=3D"https://aka.ms/ghei36" rel=3D"noreferrer noreferrer" target=
=3D"_blank">Outlook for Android</a></div>
<br>
</div>
<hr style=3D"display:inline-block;width:98%">
<div id=3D"m_-4133442876550725775m_7922344984094274404m_2723891306143681030=
m_-2768636512439875246m_-1270531741872738342divRplyFwdMsg" dir=3D"ltr"><fon=
t face=3D"Calibri, sans-serif" style=3D"font-size:11pt"><b>From:</b> Lee Ho=
wes <<a href=3D"mailto:xrikcus@gmail.com" rel=3D"noreferrer noreferrer" =
target=3D"_blank">xrikcus@gmail.com</a>><br>
<b>Sent:</b> Tuesday, October 23, 2018 9:57:09 AM<br>
<b>To:</b> <a href=3D"mailto:std-proposals@isocpp.org" rel=3D"noreferrer no=
referrer" target=3D"_blank">std-proposals@isocpp.org</a><br>
<b>Cc:</b> Brian Budge<br>
<b>Subject:</b> Re: [std-proposals] The need for std::unique_function</font=
>
<div>=C2=A0</div>
</div>
<div>
<div dir=3D"ltr">Well that was what I was thinking, but it's really up =
to you. I'm probably not the right person to advise on LEWG procedure s=
o I could easily be giving the wrong advice anyway.</div>
</div>
</div><div><br class=3D"m_-4133442876550725775m_7922344984094274404m_272389=
1306143681030m_-2768636512439875246m_-1270531741872738342webkit-block-place=
holder"></div>
-- <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" rel=3D"nore=
ferrer noreferrer" target=3D"_blank">std-proposals+unsubscribe@isocpp.org</=
a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" rel=3D"noreferrer noreferrer" 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/MW2PR1501MB2154FB67DE8B9F102CC016EEA2=
F50%40MW2PR1501MB2154.namprd15.prod.outlook.com?utm_medium=3Demail&utm_=
source=3Dfooter" rel=3D"noreferrer noreferrer" target=3D"_blank">https://gr=
oups.google.com/a/isocpp.org/d/msgid/std-proposals/MW2PR1501MB2154FB67DE8B9=
F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.com</a>.<br>
</div></blockquote></div><br></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" rel=3D"nore=
ferrer noreferrer" target=3D"_blank">std-proposals+unsubscribe@isocpp.org</=
a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" rel=3D"noreferrer noreferrer" 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/DF91B617-FD32-486E-A5B4-65AB33809C5B%=
40me.com?utm_medium=3Demail&utm_source=3Dfooter" rel=3D"noreferrer nore=
ferrer" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/st=
d-proposals/DF91B617-FD32-486E-A5B4-65AB33809C5B%40me.com</a>.<br>
</blockquote></div></div></div>
</blockquote></div>
</blockquote></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" target=3D"_=
blank">std-proposals+unsubscribe@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/CAP3wax__0hayf2KweVWRusT_xEquEkVCXRxt=
13tXutsZ0%2Baymw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r" target=3D"_blank">https://groups.google.com/a/isocpp.org/d/msgid/std-pro=
posals/CAP3wax__0hayf2KweVWRusT_xEquEkVCXRxt13tXutsZ0%2Baymw%40mail.gmail.c=
om</a>.<br>
</blockquote></div>
</blockquote></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/CAHn%2BA5P_Qcjx3RmobVoZes3VsRvXF5g6pY=
xUKfd1ru70DJq_%3DQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfooter"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAHn%2BA5P_Qc=
jx3RmobVoZes3VsRvXF5g6pYxUKfd1ru70DJq_%3DQ%40mail.gmail.com</a>.<br />
--00000000000080db800579112db7--
.
Author: Bryce Adelstein Lelbach aka wash <brycelelbach@gmail.com>
Date: Fri, 26 Oct 2018 01:26:50 -0700
Raw View
--000000000000cbc7d605791d7b7c
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
Indeed.
On Thu, Oct 25, 2018, 9:27 AM Ryan McDougall <mcdougall.ryan@gmail.com>
wrote:
> Ok I still don't have access to the mailing lists and am not sure how lon=
g
> that takes. I assume you can post in my stead until then?
>
> On Thu, Oct 25, 2018 at 2:07 AM Bryce Adelstein Lelbach aka wash <
> brycelelbach@gmail.com> wrote:
>
>>
>>
>> On Wed, Oct 24, 2018, 9:41 AM Ryan McDougall <mcdougall.ryan@gmail.com>
>> wrote:
>>
>>> From my point of view there are 2 issues:
>>> 1) Do we need std::unique_function: Yes
>>> 2) Do we want it to be move-only version of std::function, or should it
>>> be improved version where
>>> ```std::unique_function<void() const> f;``` only admits targets with
>>> const callable operators?
>>>
>>
>>
>>
>>
>> I think there's legitimate debate about latter, but it should not
>>> preclude the former. Should I just present it as an open question?
>>>
>>
>> Yes. I have not strong feelings here yet.
>>
>>
>> Lastly standardese. I don't speak it at all (yet). I can simply lift
>>> David's -- is that acceptable?
>>>
>>> To recapitulate:
>>> - Rename to P0288
>>> - Fold in P0045 as an option
>>> - Steal P0045 standardese
>>> - Ready by friday
>>>
>>> ^ This is the request?
>>>
>>
>> Yes.
>>
>> On Wed, Oct 24, 2018 at 12:00 AM Bryce Adelstein Lelbach aka wash <
>>> brycelelbach@gmail.com> wrote:
>>>
>>>> I would be willing to allocate time in LEWGI at San Diego to see this
>>>> paper, as it's a frequently requested feature.
>>>>
>>>> This comes with the caveat I'd like one updated proposal for this,
>>>> intended for discussion ready for circulation on the LEWG reflector by=
this
>>>> Friday.
>>>>
>>>>
>>>> On Tue, Oct 23, 2018, 1:59 PM 'David Krauss' via ISO C++ Standard -
>>>> Future Proposals <std-proposals@isocpp.org> wrote:
>>>>
>>>>> Hi Ryan, all,
>>>>>
>>>>> Thanks for your support! I=E2=80=99m not an active user of C++ and I =
won=E2=80=99t be
>>>>> attending the next conference, but anyone can certainly still ping me=
..
>>>>>
>>>>> Feel free to carry over the P0288 number. The main work to align the
>>>>> P0288 draft with your proposal would be rebasing the standardese onto=
the
>>>>> IS, from the current basis of P0045. Most of this can be done by reco=
vering
>>>>> the text from P0288R0.
>>>>>
>>>>> The rationale for P0288R1 depending on P0045 was that the
>>>>> shallow-const issue was spreading to this new class as a virus, so th=
e fix
>>>>> in P0045 should be applied first to contain the damage. However, two =
years
>>>>> have passed with less interest in P0045 (or another deep-const fix; a=
dding
>>>>> deep const does not imply all of P0045). The fixed, dependent version
>>>>> P0288R1 was never presented =E2=80=94 several volunteers have come fo=
rward but the
>>>>> extra complication has been a hindrance.
>>>>>
>>>>> We might focus now on building LEWG consensus on the order of
>>>>> dependencies. We=E2=80=99ve missed 2018 and there=E2=80=99s still ple=
nty of time before
>>>>> Kona 2019. If some committee members are serious about deep const as =
a hard
>>>>> requirement, then they have ample opportunity to support P0045 or to =
invent
>>>>> another solution. Otherwise, everyone should be able to agree on a
>>>>> standalone unique_function.
>>>>>
>>>>> - Best,
>>>>> David
>>>>>
>>>>>
>>>>> On 2018=E2=80=9310=E2=80=9323, at 7:35 PM, Brian Budge <bbudge@fb.com=
> wrote:
>>>>>
>>>>> David suggested to reach out to Jeffrey Yasskin on LEWG to loop him
>>>>> into the discussion.
>>>>>
>>>>> Get Outlook for Android <https://aka.ms/ghei36>
>>>>>
>>>>> ------------------------------
>>>>> *From:* Lee Howes <xrikcus@gmail.com>
>>>>> *Sent:* Tuesday, October 23, 2018 9:57:09 AM
>>>>> *To:* std-proposals@isocpp.org
>>>>> *Cc:* Brian Budge
>>>>> *Subject:* Re: [std-proposals] The need for std::unique_function
>>>>>
>>>>> Well that was what I was thinking, but it's really up to you. I'm
>>>>> probably not the right person to advise on LEWG procedure so I could =
easily
>>>>> be giving the wrong advice anyway.
>>>>>
>>>>> --
>>>>> 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, sen=
d
>>>>> 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/MW2PR150=
1MB2154FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.co=
m
>>>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/MW2PR15=
01MB2154FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.c=
om?utm_medium=3Demail&utm_source=3Dfooter>
>>>>> .
>>>>>
>>>>>
>>>>> --
>>>>> 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, sen=
d
>>>>> 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/DF91B617=
-FD32-486E-A5B4-65AB33809C5B%40me.com
>>>>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/DF91B61=
7-FD32-486E-A5B4-65AB33809C5B%40me.com?utm_medium=3Demail&utm_source=3Dfoot=
er>
>>>>> .
>>>>>
>>>> --
>> You received this message because you are subscribed to the Google Group=
s
>> "ISO C++ Standard - Future Proposals" group.
>> To unsubscribe from this group and stop receiving emails from it, send a=
n
>> 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/CAP3wax__0h=
ayf2KweVWRusT_xEquEkVCXRxt13tXutsZ0%2Baymw%40mail.gmail.com
>> <https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAP3wax__0=
hayf2KweVWRusT_xEquEkVCXRxt13tXutsZ0%2Baymw%40mail.gmail.com?utm_medium=3De=
mail&utm_source=3Dfooter>
>> .
>>
>
--=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/CAP3wax8gQXTSgtD2%3DOaJ4O8PRLx%2BQxjs-o8%2Br%2BN=
-hHn1p8dJhQ%40mail.gmail.com.
--000000000000cbc7d605791d7b7c
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable
<div dir=3D"auto">Indeed.</div><br><div class=3D"gmail_quote"><div dir=3D"l=
tr">On Thu, Oct 25, 2018, 9:27 AM Ryan McDougall <<a href=3D"mailto:mcdo=
ugall.ryan@gmail.com">mcdougall.ryan@gmail.com</a>> wrote:<br></div><blo=
ckquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #c=
cc solid;padding-left:1ex"><div dir=3D"ltr">Ok I still don't have acces=
s to the mailing lists and am not sure how long that takes. I assume you ca=
n post in my stead until then?</div><br><div class=3D"gmail_quote"><div dir=
=3D"ltr">On Thu, Oct 25, 2018 at 2:07 AM Bryce Adelstein Lelbach aka wash &=
lt;<a href=3D"mailto:brycelelbach@gmail.com" target=3D"_blank" rel=3D"noref=
errer">brycelelbach@gmail.com</a>> wrote:<br></div><blockquote class=3D"=
gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-=
left:1ex"><div dir=3D"auto"><div><br><br><div class=3D"gmail_quote"><div di=
r=3D"ltr">On Wed, Oct 24, 2018, 9:41 AM Ryan McDougall <<a href=3D"mailt=
o:mcdougall.ryan@gmail.com" target=3D"_blank" rel=3D"noreferrer">mcdougall.=
ryan@gmail.com</a>> wrote:<br></div><blockquote class=3D"gmail_quote" st=
yle=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div =
dir=3D"ltr">From my point of view there are 2 issues:<div>1) Do we need std=
::unique_function: Yes<br>2) Do we want it to be move-only version of std::=
function, or should it be improved version where<br>```std::unique_function=
<void() const> f;``` only admits targets with const callable operator=
s?<br></div></div></blockquote></div></div><div dir=3D"auto"><br></div><div=
dir=3D"auto"><br></div><div dir=3D"auto"><br></div><div dir=3D"auto"><br><=
/div><div dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"gmai=
l_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left=
:1ex"><div dir=3D"ltr"><div>I think there's legitimate debate about lat=
ter, but it should not preclude the former. Should I just present it as an =
open question?</div></div></blockquote></div></div><div dir=3D"auto"><br></=
div><div dir=3D"auto">Yes. I have not strong feelings here yet.</div><div d=
ir=3D"auto"></div><div dir=3D"auto"><br></div><div dir=3D"auto"><br></div><=
div dir=3D"auto"><div class=3D"gmail_quote"><blockquote class=3D"gmail_quot=
e" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">=
<div dir=3D"ltr"><div>Lastly standardese. I don't speak it at all (yet)=
.. I can simply lift David's -- is that acceptable?<br><br>To recapitula=
te:<br>- Rename to P0288<br>- Fold in P0045 as an option<br>- Steal P0045 s=
tandardese<br>- Ready by friday<br><br>^ This is the request?</div></div></=
blockquote></div></div><div dir=3D"auto"><br></div><div dir=3D"auto">Yes.</=
div><div dir=3D"auto"><br></div><div dir=3D"auto"><div class=3D"gmail_quote=
"><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:=
1px #ccc solid;padding-left:1ex"><div class=3D"gmail_quote"><div dir=3D"ltr=
">On Wed, Oct 24, 2018 at 12:00 AM Bryce Adelstein Lelbach aka wash <<a =
href=3D"mailto:brycelelbach@gmail.com" rel=3D"noreferrer noreferrer" target=
=3D"_blank">brycelelbach@gmail.com</a>> wrote:<br></div><blockquote clas=
s=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1px #ccc solid;pad=
ding-left:1ex"><div dir=3D"auto"><div>I would be willing to allocate time i=
n LEWGI at San Diego to see this paper, as it's a frequently requested =
feature.<div dir=3D"auto"><br></div><div dir=3D"auto">This comes with the c=
aveat I'd like one updated proposal for this, intended for discussion r=
eady for circulation on the LEWG reflector by this Friday.</div><div dir=3D=
"auto"><br></div><br><div class=3D"gmail_quote"><div dir=3D"ltr">On Tue, Oc=
t 23, 2018, 1:59 PM 'David Krauss' via ISO C++ Standard - Future Pr=
oposals <<a href=3D"mailto:std-proposals@isocpp.org" rel=3D"noreferrer n=
oreferrer" target=3D"_blank">std-proposals@isocpp.org</a>> wrote:<br></d=
iv><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left=
:1px #ccc solid;padding-left:1ex"><div style=3D"word-wrap:break-word">Hi Ry=
an, all,<div><br></div><div>Thanks for your support! I=E2=80=99m not an act=
ive user of C++ and I won=E2=80=99t be attending the next conference, but a=
nyone can certainly still ping me.</div><div><br></div><div>Feel free to ca=
rry over the P0288 number. The main work to align the P0288 draft with your=
proposal would be rebasing the standardese onto the IS, from the current b=
asis of P0045. Most of this can be done by recovering the text from P0288R0=
..</div><div><br></div><div>The rationale for P0288R1 depending on P0045 was=
that the shallow-const issue was spreading to this new class as a virus, s=
o the fix in P0045 should be applied first to contain the damage. However, =
two years have passed with less interest in P0045 (or another deep-const fi=
x; adding deep const does not imply all of P0045). The fixed, dependent ver=
sion P0288R1 was never presented =E2=80=94 several volunteers have come for=
ward but the extra complication has been a hindrance.</div><div><br></div><=
div>We might focus now on building LEWG consensus on the order of dependenc=
ies. We=E2=80=99ve missed 2018 and there=E2=80=99s still plenty of time bef=
ore Kona 2019. If some committee members are serious about deep const as a =
hard requirement, then they have ample opportunity to support P0045 or to i=
nvent another solution. Otherwise, everyone should be able to agree on a st=
andalone <font face=3D"Courier">unique_function</font>.</div><div><br></div=
><div><span class=3D"m_9176058040117614822m_7922344984094274404m_2723891306=
143681030m_-2768636512439875246m_-1270531741872738342Apple-tab-span" style=
=3D"white-space:pre-wrap"> </span>- Best,</div><div><span class=3D"m_917605=
8040117614822m_7922344984094274404m_2723891306143681030m_-27686365124398752=
46m_-1270531741872738342Apple-tab-span" style=3D"white-space:pre-wrap"> </s=
pan>David</div><div><br></div><div><br><div><blockquote type=3D"cite"><div>=
On 2018=E2=80=9310=E2=80=9323, at 7:35 PM, Brian Budge <<a href=3D"mailt=
o:bbudge@fb.com" rel=3D"noreferrer noreferrer noreferrer" target=3D"_blank"=
>bbudge@fb.com</a>> wrote:</div><br class=3D"m_9176058040117614822m_7922=
344984094274404m_2723891306143681030m_-2768636512439875246m_-12705317418727=
38342Apple-interchange-newline"><div>
<div>
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
David suggested to reach out to Jeffrey Yasskin on LEWG to loop him into th=
e discussion.<br>
<br>
</div>
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
<div dir=3D"auto" style=3D"direction:ltr;margin:0px;padding:0px;font-family=
:sans-serif;font-size:11pt">
Get <a href=3D"https://aka.ms/ghei36" rel=3D"noreferrer noreferrer noreferr=
er" target=3D"_blank">Outlook for Android</a></div>
<br>
</div>
<hr style=3D"display:inline-block;width:98%">
<div id=3D"m_9176058040117614822m_7922344984094274404m_2723891306143681030m=
_-2768636512439875246m_-1270531741872738342divRplyFwdMsg" dir=3D"ltr"><font=
face=3D"Calibri, sans-serif" style=3D"font-size:11pt"><b>From:</b> Lee How=
es <<a href=3D"mailto:xrikcus@gmail.com" rel=3D"noreferrer noreferrer no=
referrer" target=3D"_blank">xrikcus@gmail.com</a>><br>
<b>Sent:</b> Tuesday, October 23, 2018 9:57:09 AM<br>
<b>To:</b> <a href=3D"mailto:std-proposals@isocpp.org" rel=3D"noreferrer no=
referrer noreferrer" target=3D"_blank">std-proposals@isocpp.org</a><br>
<b>Cc:</b> Brian Budge<br>
<b>Subject:</b> Re: [std-proposals] The need for std::unique_function</font=
>
<div>=C2=A0</div>
</div>
<div>
<div dir=3D"ltr">Well that was what I was thinking, but it's really up =
to you. I'm probably not the right person to advise on LEWG procedure s=
o I could easily be giving the wrong advice anyway.</div>
</div>
</div><div><br class=3D"m_9176058040117614822m_7922344984094274404m_2723891=
306143681030m_-2768636512439875246m_-1270531741872738342webkit-block-placeh=
older"></div>
-- <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" rel=3D"nore=
ferrer noreferrer noreferrer" target=3D"_blank">std-proposals+unsubscribe@i=
socpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" rel=3D"noreferrer noreferrer noreferrer" target=3D"_blank">std-propos=
als@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/MW2PR1501MB2154FB67DE8B9F102CC016EEA2=
F50%40MW2PR1501MB2154.namprd15.prod.outlook.com?utm_medium=3Demail&utm_=
source=3Dfooter" rel=3D"noreferrer noreferrer noreferrer" target=3D"_blank"=
>https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/MW2PR1501MB21=
54FB67DE8B9F102CC016EEA2F50%40MW2PR1501MB2154.namprd15.prod.outlook.com</a>=
..<br>
</div></blockquote></div><br></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" rel=3D"nore=
ferrer noreferrer noreferrer" target=3D"_blank">std-proposals+unsubscribe@i=
socpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" rel=3D"noreferrer noreferrer noreferrer" target=3D"_blank">std-propos=
als@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/DF91B617-FD32-486E-A5B4-65AB33809C5B%=
40me.com?utm_medium=3Demail&utm_source=3Dfooter" rel=3D"noreferrer nore=
ferrer noreferrer" target=3D"_blank">https://groups.google.com/a/isocpp.org=
/d/msgid/std-proposals/DF91B617-FD32-486E-A5B4-65AB33809C5B%40me.com</a>.<b=
r>
</blockquote></div></div></div>
</blockquote></div>
</blockquote></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" target=3D"_=
blank" rel=3D"noreferrer">std-proposals+unsubscribe@isocpp.org</a>.<br>
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org" target=3D"_blank" rel=3D"noreferrer">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/CAP3wax__0hayf2KweVWRusT_xEquEkVCXRxt=
13tXutsZ0%2Baymw%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoote=
r" target=3D"_blank" rel=3D"noreferrer">https://groups.google.com/a/isocpp.=
org/d/msgid/std-proposals/CAP3wax__0hayf2KweVWRusT_xEquEkVCXRxt13tXutsZ0%2B=
aymw%40mail.gmail.com</a>.<br>
</blockquote></div>
</blockquote></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/CAP3wax8gQXTSgtD2%3DOaJ4O8PRLx%2BQxjs=
-o8%2Br%2BN-hHn1p8dJhQ%40mail.gmail.com?utm_medium=3Demail&utm_source=3Dfoo=
ter">https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/CAP3wax8g=
QXTSgtD2%3DOaJ4O8PRLx%2BQxjs-o8%2Br%2BN-hHn1p8dJhQ%40mail.gmail.com</a>.<br=
/>
--000000000000cbc7d605791d7b7c--
.