220 40687 <CAHn+A5NHiEO1rTKfZOryWnW-NTqLGgim6epp-Bt03iU5wd-EEA@mail.gmail.com> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Ryan McDougall <mcdougall.ryan@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: The need for std::unique_function
Date: Tue, 23 Oct 2018 09:17:45 -0700
Lines: 1590
Approved: news@gmane.org
Message-ID: <CAHn+A5NHiEO1rTKfZOryWnW-NTqLGgim6epp-Bt03iU5wd-EEA@mail.gmail.com>
References: <CAHn+A5NyaUQjAeudtObjn08Trz4iJ+u-GGt2J5VnmtmZJiPVxg@mail.gmail.com>
 <CAJH_FNW1PVw2BeYJCWfKNKN3_67eLY_6wG1vgNJOZx9oQS+s=Q@mail.gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; boundary="0000000000007e6af00578e7b6b2"
X-Trace: blaine.gmane.org 1540311355 29493 195.159.176.226 (23 Oct 2018 16:15:55 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Tue, 23 Oct 2018 16:15:55 +0000 (UTC)
Cc: bbudge@fb.com
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBDS4B5X37MCRBN4TXXPAKGQEE5NJUTA@isocpp.org Tue Oct 23 18:15:51 2018
Return-path: <std-proposals+bncBDS4B5X37MCRBN4TXXPAKGQEE5NJUTA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-wm1-f70.google.com ([209.85.128.70])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBDS4B5X37MCRBN4TXXPAKGQEE5NJUTA@isocpp.org>)
	id 1gEzLS-0007aI-64
	for gclcip-std-proposals@m.gmane.org; Tue, 23 Oct 2018 18:15:50 +0200
Original-Received: by mail-wm1-f70.google.com with SMTP id y185-v6sf1572873wmg.6
        for <gclcip-std-proposals@m.gmane.org>; Tue, 23 Oct 2018 09:18:01 -0700 (PDT)
ARC-Seal: i=2; a=rsa-sha256; t=1540311481; cv=pass;
        d=google.com; s=arc-20160816;
        b=NRg2ABBFOyK9La1NV7Dngs2hF5Edub26cJUzZln671hzJcY4FprHIRVEwjPmwKMszg
         AiQgC767TQyr4a4r2CQaJyxyeZ9uslFLvRFfp4+5eVayPTs/lu+/ls5TzekxUlmz/Lwu
         we1xUUHsmtygBy1Vkm6dNsGXK13r+Hydxz21nUaX3LlCLCkgP/8DOeaUVPEZ7fTn3WV0
         /+mNNXmRITpak96YwuE81UKk5h05bhWShn86sz0TrWS0/gEjbbzaLS8KaXIQT/k38BMZ
         DevZvhuUoftM6WmETh7ccIJKsUcES176CIXc6LA63I/6FbUFcCi/vajP6E87zbcG4Nq4
         bXEQ==
ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=list-unsubscribe:list-subscribe:list-archive:list-help:list-post
         :list-id:mailing-list:precedence:reply-to:cc:to:subject:message-id
         :date:from:in-reply-to:references:mime-version:dkim-signature;
        bh=E1qukJzhESJSO6oVkTYTLrInMYQeh+fwScMFIsOxnbE=;
        b=SRoGZbluPjsA+0AgxH/NnudF9yr9fLzu8DZdNHtaOVKWXfqSikcOIoZbzR9C024q74
         +ok/n97EUJFJ+Rxo5D69lJmIsGowIxhnakhnwF5JexXnjxa6URI0fIaYH7+VERV5aJ0C
         aq/tqZu8aw32rNAsdy8iaxxMYiBtVHw3X4Vqyv1s//Ye/vEUzPzVC9oLsC7HwLACJhww
         HI4TxOmZTCdguVNtk1NsKqyHIX4z/2ysx9m1V18oG8wattfSuOJ/IeYy7f0fQ76jUDfP
         j9oVVE1MySdmMAacj7Ij61HNT+hFy50SWnTBhqnBnjVuedErUpYAF23jLwxBzNlF2GbL
         U07Q==
ARC-Authentication-Results: i=2; mx.google.com;
       dkim=pass header.i=@gmail.com header.s=20161025 header.b=F0brPC7v;
       spf=pass (google.com: domain of mcdougall.ryan@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=mcdougall.ryan@gmail.com;
       dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=mime-version:references:in-reply-to:from:date:message-id:subject:to
         :cc:x-original-sender:x-original-authentication-results:reply-to
         :precedence:mailing-list:list-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=E1qukJzhESJSO6oVkTYTLrInMYQeh+fwScMFIsOxnbE=;
        b=rkTKpVO8Thk2C+kHqvez6FsBcn4lYA6ZCqMHh1vkL8DDLFEyziVx2eybsh/SpiFSJC
         pwaP+0hNrDO0Iq8+kAlRILndJ4TEQZ5Ux9Io7LnHfpI9AxamOJjTEunwpDaqmFhhectg
         Yi8oDXM/hfaEgPqAiGgncXoUosRXtgzuxxOonfBGUMOsWQKwA+/HIhDDpeRIzr4aZ2+o
         i+4O1b4en5dGFtUO7igNnCYPaUdRaIe/qhItc2g8UACTk8G33DeDbj1LVB2IqcRJdwZZ
         EYRV3VyCi3XtOtH28AG+g/A50gRabPVppNkBfnAWvE0xY8QgLlkkkd2zmpCRzLF34kNU
         A/Pg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:mime-version:references:in-reply-to:from:date
         :message-id:subject:to:cc:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=E1qukJzhESJSO6oVkTYTLrInMYQeh+fwScMFIsOxnbE=;
        b=d8jVbL/eC3nxy/4VB5sLHoiRze3CShorEMe5aA/xKUegh7fuKXo/5D8VOBPqXGqucT
         RXaCd3UGQA33SgKgO2J8Px0CzDw6mocMvHevQH/f34A+S4ZeiTcbKRnreZefL/MtXptQ
         fn24xEavl8JQ0dg4WdLvZE9YtBoqYDqYjJ2H0bTK368a8TJbWMPaW+PU1+6ZNtwbXsOX
         g0DVlYx4HFW8VidA1H1tOwehDUTnuBiLDvlt9k2aOcV0ZQepmDzB2X0Luqo+omewtaNM
         TT1fEsfyff1HK6SZ1c4iqaPf6cQASJuOWI21oow3PXxsQzDWfifKlHIqLc2/x6YBWnhV
         Hqpw==
X-Gm-Message-State: ABuFfogINNgQgObtxlQtSdwgZ9t7UiFXz+8HCTUgXSxmdUOXMJx20JK6
	LoD8VHvjSotzPe0nEC0hPRWyPg==
X-Google-Smtp-Source: ACcGV60WvC4zFp2gOGikOuVn8IVgca+EUYdeVmdoILrYEnkMcCJD3kx+3MCG9OYn6W2ykFL4hOMuYg==
X-Received: by 2002:a1c:d8:: with SMTP id 207-v6mr2309999wma.12.1540311480826;
        Tue, 23 Oct 2018 09:18:00 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 2002:adf:8b97:: with SMTP id o23-v6ls891318wra.15.gmail; Tue, 23
 Oct 2018 09:17:59 -0700 (PDT)
X-Received: by 2002:a5d:420d:: with SMTP id n13-v6mr25864560wrq.201.1540311479199;
        Tue, 23 Oct 2018 09:17:59 -0700 (PDT)
ARC-Seal: i=1; a=rsa-sha256; t=1540311479; cv=none;
        d=google.com; s=arc-20160816;
        b=bVAjtL+Z8BJ46dzSdhARhwozKhX1h1NmN1bX5Vneo96pEtJBvexY4BlyQXcJO7DcVj
         sbz6/vkmoKQFshXpFPMpU/WHm9EgGCxRu/AJTsXj9N4JD0A7sFy2QhxbbJX4s8mnqGAa
         lFyDW7juQw2px+iVYRewZE4bbrVayqH5ZUnAHfyiHqmIJi+dUsEQAAxZAvlu/pH8mjaP
         RBB8Zxhoq1tNMJChOOBXtIHyKXk3f4sTZH0J+kBbwBamygEfat/1iVUms2khPXxu1lNU
         wMEPkNcdDdb3a3yiw/yzTVJcUjlYZt1kmR0zSn+JhI2v5fxxw7jDpzHYRG4FkooP90fS
         CAyg==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816;
        h=cc:to:subject:message-id:date:from:in-reply-to:references
         :mime-version:dkim-signature;
        bh=jzXvbV7DkfkiHJ0xNRBrnYKdTt9m9eGtuOHp4CKSFhw=;
        b=irA/Tu6f8I38v4fakkq65eg9q/CuTPfjtNgIAn1qnD+qUnKFoO/Uu0Sq4SKD4jr5rq
         D15MaKymmO7iGUu/T3T1SiP7YWSOicVcjzKuYC4fSzvlYhicHKRu2ANO7IOXD/VkQf4D
         dWzgblHlvEnFp0N/6SB6phZKmfe8HVKy2WNI4NzvFJu/y1IFmsC+J6MIxlFe9j1Kbg6g
         wCQy/CFJBvPoERiE/CyzSQnHvWM2LXgCIXTWfwrFbgzxbJBE4IrOpV4WFxskUjnoTee/
         /hUkV2QXiGIal3N8z3uWyqbVHPsMYKqnfYaPCg87dWcq9Pe/wPkXOr6wov1YVyR5Hq5t
         IrVw==
ARC-Authentication-Results: i=1; mx.google.com;
       dkim=pass header.i=@gmail.com header.s=20161025 header.b=F0brPC7v;
       spf=pass (google.com: domain of mcdougall.ryan@gmail.com designates 209.85.220.41 as permitted sender) smtp.mailfrom=mcdougall.ryan@gmail.com;
       dmarc=pass (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com
Original-Received: from mail-sor-f41.google.com (mail-sor-f41.google.com. [209.85.220.41])
        by mx.google.com with SMTPS id 6-v6sor1388096wmy.21.2018.10.23.09.17.59
        for <std-proposals@isocpp.org>
        (Google Transport Security);
        Tue, 23 Oct 2018 09:17:59 -0700 (PDT)
Received-SPF: pass (google.com: domain of mcdougall.ryan@gmail.com designates 209.85.220.41 as permitted sender) client-ip=209.85.220.41;
X-Received: by 2002:a1c:2dc5:: with SMTP id t188-v6mr19965422wmt.94.1540311478068;
 Tue, 23 Oct 2018 09:17:58 -0700 (PDT)
In-Reply-To: <CAJH_FNW1PVw2BeYJCWfKNKN3_67eLY_6wG1vgNJOZx9oQS+s=Q@mail.gmail.com>
X-Original-Sender: mcdougall.ryan@gmail.com
X-Original-Authentication-Results: mx.google.com;       dkim=pass
 header.i=@gmail.com header.s=20161025 header.b=F0brPC7v;       spf=pass
 (google.com: domain of mcdougall.ryan@gmail.com designates 209.85.220.41 as
 permitted sender) smtp.mailfrom=mcdougall.ryan@gmail.com;       dmarc=pass
 (p=NONE sp=QUARANTINE dis=NONE) header.from=gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Spam-Checked-In-Group: std-proposals@isocpp.org
X-Google-Group-Id: 399137483710
List-Post: <https://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <https://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <https://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>,
 <https://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:40687
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/40687>

--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&#39;ll be at SD in order to push this paper -- thou=
ght I don&#39;t know if there&#39;s room on anyone schedule. I have hope ho=
wever since it&#39;s relatively uncontroversial it can yet be fast tracked.=
 I would very much like help with wording if you&#39;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 &lt;<a href=3D"mailto:xrikcus@=
gmail.com">xrikcus@gmail.com</a>&gt; 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 &lt;<a href=
=3D"mailto:mcdougall.ryan@gmail.com" target=3D"_blank">mcdougall.ryan@gmail=
..com</a>&gt; 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&#39;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:&quot;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=
:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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&lt;Blob&gt; 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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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&lt;std::string, std::function&lt;void()&gt;&gt; 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:&quot;Courier New&quot;;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:&quot;Courier New=
&quot;;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, [&amp;] {</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:&quot;Courier New&quot;;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:&quot;Co=
urier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courie=
r New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New=
&quot;;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&lt;BankTransfer&gt;(=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&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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-=
&gt;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=
:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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&lt;std::function&lt;int(=
)&gt;&gt; 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:&quot;Courier New&quot;;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&quot;;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:&quot;Courier New&quot;;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&lt;std::packaged_task&=
lt;int()&gt;&gt; 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:&quot;Courier New&quot;;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&lt;int&gt; 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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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([&amp;] {</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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;=
;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:&quot;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:&quot;C=
ourier New&quot;;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:&quot;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&lt;Foo&gt; 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:&quot;Courier New&quot;;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&lt;Foo&gt; 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:&quot;Courier New&quot;;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=
&lt;std::function&lt;void()&gt;&gt; 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:&quot;Courier New&quot;;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&lt;std::unique_function&=
lt;void()&gt;&gt; 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&quot;;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:&quot;Courier New&quot;;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&lt;Foo&gt;(move(f));</span><span style=3D"font-size:10pt;f=
ont-family:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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-&gt;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;=
;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:&quot;Courier N=
ew&quot;;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:&quot;Courier New&quot;;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:&quot;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:&quot;Courier New&quot;;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-&gt;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;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-&gt;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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&quot;;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-&gt;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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&lt;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&quot;;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([&amp;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;=
;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:&quot;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:&quot;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:&quot;Courier=
 New&quot;;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:&quot;Cour=
ier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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-&gt;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:&quot;Courie=
r New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier Ne=
w&quot;;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&lt;void()&gt; c =3D C{}; // Copy-only</span><span s=
tyle=3D"font-size:11pt;font-family:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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&lt;void()&gt; 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:&quot;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot=
;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Cour=
ier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;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:=
&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier N=
ew&quot;;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&lt;void() const&gt; 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:&quot;Courier New&quot;;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&lt;void()&gt; 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:&quot;Co=
urier New&quot;;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&lt;void()&gt; 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:&quot;Courier New&quot;;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&lt;void() const&gt; 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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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:&quot;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&lt;void()&gt; 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:&quot;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&lt;void()&gt; 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:&quot;Courier New&quot;;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:&quot;Courier New&quot;;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&quot; 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&amp;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&quot; 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&amp;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&quot; 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--

.
