220 32353 <d15cc3d3-b526-499d-9b8b-2d4ecd15aba9@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Mingxin Wang <wmx16835vv@163.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: =?UTF-8?B?UmU6IFtzdGQtcHJvcG9zYWxzXSBSZTogQWRkaW5nIHRoZSBLZXl3b3JkIOKAnGludGVyZg==?=
	=?UTF-8?B?YWNl4oCdIGluIEMrKw==?=
Date: Tue, 9 May 2017 01:01:48 -0700 (PDT)
Lines: 266
Approved: news@gmane.org
Message-ID: <d15cc3d3-b526-499d-9b8b-2d4ecd15aba9@isocpp.org>
References: <c8742174-fef0-44a9-988d-2c8aebba9243@isocpp.org>
 <CACL3gUXPSVdsT0Z77igxGVtHU9ALGPcN=7hwKKKfBmt8eQmXtA@mail.gmail.com>
 <9ee212eb-4037-40c4-94c3-57a9a170a4c3@isocpp.org> <1765502.4y06pMOS3s@tjmaciei-mobl1>
 <e8fb03f4-8c94-46c2-a612-acab81117998@isocpp.org>
 <CAOHCbiswurpbE6tG3igWTsFfpJ=LAeT9PoTUZBNsrnMOhEwSxQ@mail.gmail.com>
 <6bfa8a30-a2c4-46d5-8ac2-c0353408a041@isocpp.org>
 <9ef42c60-5709-4472-97f0-e68fb9960840@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_4928_340421383.1494316908861"
X-Trace: blaine.gmane.org 1494316917 405 195.159.176.226 (9 May 2017 08:01:57 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Tue, 9 May 2017 08:01:57 +0000 (UTC)
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBDNMBNHJWIGBB3POYXEAKGQE4ESQPFI@isocpp.org Tue May 09 10:01:45 2017
Return-path: <std-proposals+bncBDNMBNHJWIGBB3POYXEAKGQE4ESQPFI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-io0-f197.google.com ([209.85.223.197])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBDNMBNHJWIGBB3POYXEAKGQE4ESQPFI@isocpp.org>)
	id 1d805Z-0008Jn-8c
	for gclcip-std-proposals@m.gmane.org; Tue, 09 May 2017 10:01:45 +0200
Original-Received: by mail-io0-f197.google.com with SMTP id c135sf72337931ioe.13
        for <gclcip-std-proposals@m.gmane.org>; Tue, 09 May 2017 01:01:51 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :x-spam-checked-in-group:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe;
        bh=+7yUmKJhUcaV0Yw+K82m8Ofeo9gZ2dov/xvQmhVBLuw=;
        b=EbxM0NR9dxzB/SqGjcdgjV/AFg2Mmib84l5S7Fz8VKl1u2CDgfh8EJ+kyF2P+j1Y4N
         KJu5hjoQdg14lQ3Fd0zTNOK7VN012N/gJsC0nKSPnDYXaAHaUbnC09PCAeumZjAOxhht
         2AU8m+QsvuqBGWJrc1C6nv2fR5pHAnQCJGntX6HC9cC9PQbW+7YCIGq/pDKFOof2+JvT
         YyQW/2ACLnhn43S7bqNxSPeg86YmB0b+MKwlM1VOozWo8yI1wMrl46LRQdffuFu672rw
         /X+kuLY6Th7FigSf1HqIYSLHPIRUf0aZfveV9s0ep4LS+2mxQEDwwUEOByKjBM12wvv2
         ROoA==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20161025;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:x-original-sender:reply-to:precedence
         :mailing-list:list-id:x-spam-checked-in-group:list-post:list-help
         :list-archive:list-subscribe:list-unsubscribe;
        bh=+7yUmKJhUcaV0Yw+K82m8Ofeo9gZ2dov/xvQmhVBLuw=;
        b=tLceV0ukUWzalqzsErxnpUEYUZwdD8FSjO9cNDTiLgOqPyfTDy7WAxpXcXEkPwvv2i
         6DWVeRq3wwkYjO4YLRKEehoBQ1G3XFuWwRZM3tj5wHti5HmYxF/4EVkSVFlJGQNGny3I
         Hge+q9HTIa/6H2v3FX9OdXFddqqQ/Y1g76gJO1JWsD6xOEtjeRNau517ZK/ic51n0YPb
         pj9/0b36BkNeTwuSO+CUB9LMQYRLAjC9lyIoXIoo/Sp4x2hsHkBioQWg5c3+z9UIDGvw
         KKG/n2t6tdWSdBOFiKRsLC6/lX11I1Mc5Uwe0vvMXL0rNwSF9HGSc3fzJU0fMQhF+tKL
         etxg==
X-Gm-Message-State: AN3rC/4pns9YB3zeXb7t7kt6jcOtcOeXvFyV2tHpJXZ6QQKUU+GpWg6W
	gOAvwrTCKmwGVA==
X-Received: by 10.36.170.15 with SMTP id b15mr10223908itf.27.1494316910468;
        Tue, 09 May 2017 01:01:50 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.157.40.137 with SMTP id s9ls10603343ota.44.gmail; Tue, 09 May
 2017 01:01:49 -0700 (PDT)
X-Received: by 10.157.84.44 with SMTP id j44mr1347408oth.16.1494316909467;
        Tue, 09 May 2017 01:01:49 -0700 (PDT)
In-Reply-To: <9ef42c60-5709-4472-97f0-e68fb9960840@isocpp.org>
X-Original-Sender: wmx16835vv@163.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <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:32353
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/32353>

------=_Part_4928_340421383.1494316908861
Content-Type: multipart/alternative; 
	boundary="----=_Part_4929_1991480419.1494316908861"

------=_Part_4929_1991480419.1494316908861
Content-Type: text/plain; charset=UTF-8

Dear Mr. Barry Revzin,

This feature is possible to be implemented with virtual functions and smart 
pointers. The "reflections" usually introduces much runtime overhead than 
virtual functions, thus I tend to use the latter.

Specifically, I tend to use the following architecture to implement:

<https://lh3.googleusercontent.com/-qA3Nkvys7YE/WRF2vmJ2v9I/AAAAAAAAADk/ToqJoRWyzGEnUt2CvwOfpA76uy5VelMWwCLcB/s1600/Untitled.png>

For example, for a interface Foo:
interface Foo {
  Foo copy();
  void operator()();
  Foo f();
  void g(int);
};

The following code may be generated:
class Foo {
 public:
  template <class Data>
  Foo(Data data) requires
      MoveConstructible<Data>() &&
      requires(Data data, int arg_0) {
        { data() };
        { data.g(std::move(arg_0)) };
      } && (requires(Data data) {
        { data.f() } -> Data;
      } || requires(Data data) {
        { data.f() } -> Foo;
      }) : data_(new Implementation<Data>(std::move(data))) {}
  Foo() = default;
  Foo(Foo&&) = default;
  Foo(const Foo&) = default;
  Foo& operator=(Foo&&) = default;
  Foo& operator=(const Foo&) = default;

  Foo copy() { return data_->op_0(); }
  void operator()() { data_->op_1(); };
  Foo f() { return data_->op_2(); }
  void g(int arg_0) { data_->op_3(std::move(arg_0)); }

 private:
  class Abstraction {
   public:
    virtual Foo op_0() = 0;
    virtual void op_1() = 0;
    virtual Foo op_2() = 0;
    virtual void op_3(int&&) = 0;
    virtual ~Abstraction() {}
  };

  template <class Data>
  class Implementation final : public Abstraction {
   public:
    Implementation(Data&& data) : data_(std::forward<Data>(data)) {}
    Foo op_0() override { return Data(data_); }
    void op_1() override { data_(); }
    Foo op_2() override { return data_.f(); }
    void op_3(int&& arg_0) override { data_.g(std::forward<int>(arg_0)); }

   private:
    Data data_;
  };

  std::shared_ptr<Abstraction> data_;
};




On Tuesday, May 9, 2017 at 5:27:34 AM UTC+8, Barry Revzin wrote:
>
> Yep, I think we are talking about automatic type-erasure here.
>>>
>>> Sean Parent has done a lot of work with type-erasure and polymorphic 
>>> values types based on "concepts" (pre Concepts concepts).
>>>
>>> I wonder if Concepts + reflection might allow someone to write:
>>>
>>> Foo foo; // foo happens to model Concept
>>> std::erased<Concept> efoo = foo;
>>> func(efoo);  // Not a templatized function
>>>
>>> Tony
>>>
>>
>> That would require lots of things that don't exist at present:
>>
>> 1: Reflection to be able to introspect concepts, being able to iterate 
>> over their constituent expressions.
>>
>> 2: Reflection would need to be able to *generate* code. Otherwise, 
>> `std::erased` wouldn't be able to generate non-member functions to handle 
>> non-members of the `Concept`.
>>
>> 3: Concepts would have to be able to be passed as template parameters.
>>
>
> Yeah, but I'd argue it's really what you want. Type erasure is extremely 
> useful, Concepts already express the desired interface, so it's really 
> natural to stick them together. It'd be pretty valuable to either:
>
> (1) be able to write a library that works like erased<Concept> (e.g. 
> Rust's Box)
> (2) provide a mechanism in the language to implicitly generate such a 
> thing, whether by
> (2a) reappropriating the abbreviated function syntax to do type erasure 
> instead, or 
> (2b) providing a new syntax like void foo(Concept^ ) 
>
> Any of those approaches requires a lot of stuff that we don't have today, 
> and won't have on day 1 on any of these TSes hitting, but I think are worth 
> considering longer term as next steps for cool problems to solve with 
> Concepts.
>

-- 
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/d15cc3d3-b526-499d-9b8b-2d4ecd15aba9%40isocpp.org.

------=_Part_4929_1991480419.1494316908861
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div><div><font face=3D"georgia, serif">Dear Mr. Barry Rev=
zin,</font></div><div><font face=3D"georgia, serif"><br></font></div><div><=
font face=3D"georgia, serif">This feature is possible to be implemented wit=
h virtual functions and smart pointers. The &quot;reflections&quot; usually=
 introduces much runtime overhead than virtual functions, thus I tend to us=
e the latter.</font></div><div><font face=3D"georgia, serif"><br></font></d=
iv><div><font face=3D"georgia, serif">Specifically, I tend to use the follo=
wing architecture to implement:</font></div></div><div><br></div><p class=
=3D"separator" style=3D"text-align: center; clear: both;"><a imageanchor=3D=
"1" href=3D"https://lh3.googleusercontent.com/-qA3Nkvys7YE/WRF2vmJ2v9I/AAAA=
AAAAADk/ToqJoRWyzGEnUt2CvwOfpA76uy5VelMWwCLcB/s1600/Untitled.png" style=3D"=
margin-left: 1em; margin-right: 1em;"><img src=3D"https://lh3.googleusercon=
tent.com/-qA3Nkvys7YE/WRF2vmJ2v9I/AAAAAAAAADk/ToqJoRWyzGEnUt2CvwOfpA76uy5Ve=
lMWwCLcB/s400/Untitled.png" border=3D"0" width=3D"400" height=3D"142"></a><=
/p><div><font face=3D"georgia, serif"><br></font></div><div><font face=3D"g=
eorgia, serif">For example, for a interface Foo:</font></div><div><font fac=
e=3D"georgia, serif"><div class=3D"prettyprint" style=3D"border: 1px solid =
rgb(187, 187, 187); word-wrap: break-word; background-color: rgb(250, 250, =
250);"><code class=3D"prettyprint"><div class=3D"subprettyprint"><div class=
=3D"subprettyprint">interface Foo {</div><div class=3D"subprettyprint">=C2=
=A0 Foo copy();</div><div class=3D"subprettyprint">=C2=A0 void operator()()=
;</div><div class=3D"subprettyprint">=C2=A0 Foo f();</div><div class=3D"sub=
prettyprint">=C2=A0 void g(int);</div><div class=3D"subprettyprint">};</div=
></div></code></div><br>The following code may be generated:</font></div><d=
iv><div class=3D"prettyprint" style=3D"border: 1px solid rgb(187, 187, 187)=
; word-wrap: break-word; background-color: rgb(250, 250, 250);"><code class=
=3D"prettyprint"><div class=3D"subprettyprint"><font color=3D"#660066"><div=
 class=3D"subprettyprint">class Foo {</div><div class=3D"subprettyprint">=
=C2=A0public:</div><div class=3D"subprettyprint">=C2=A0 template &lt;class =
Data&gt;</div><div class=3D"subprettyprint">=C2=A0 Foo(Data data) requires<=
/div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 MoveConstructible&l=
t;Data&gt;() &amp;&amp;</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =
=C2=A0 requires(Data data, int arg_0) {</div><div class=3D"subprettyprint">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 { data() };</div><div class=3D"subprettyprint">=
=C2=A0 =C2=A0 =C2=A0 =C2=A0 { data.g(std::move(arg_0)) };</div><div class=
=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 } &amp;&amp; (requires(Data data) =
{</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 =C2=A0 { data.f()=
 } -&gt; Data;</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=A0 } ||=
 requires(Data data) {</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 =C2=
=A0 =C2=A0 { data.f() } -&gt; Foo;</div><div class=3D"subprettyprint">=C2=
=A0 =C2=A0 =C2=A0 }) : data_(new Implementation&lt;Data&gt;(std::move(data)=
)) {}</div><div class=3D"subprettyprint">=C2=A0 Foo() =3D default;</div><di=
v class=3D"subprettyprint">=C2=A0 Foo(Foo&amp;&amp;) =3D default;</div><div=
 class=3D"subprettyprint">=C2=A0 Foo(const Foo&amp;) =3D default;</div><div=
 class=3D"subprettyprint">=C2=A0 Foo&amp; operator=3D(Foo&amp;&amp;) =3D de=
fault;</div><div class=3D"subprettyprint">=C2=A0 Foo&amp; operator=3D(const=
 Foo&amp;) =3D default;</div><div class=3D"subprettyprint"><br></div><div c=
lass=3D"subprettyprint">=C2=A0 Foo copy() { return data_-&gt;op_0(); }</div=
><div class=3D"subprettyprint">=C2=A0 void operator()() { data_-&gt;op_1();=
 };</div><div class=3D"subprettyprint">=C2=A0 Foo f() { return data_-&gt;op=
_2(); }</div><div class=3D"subprettyprint">=C2=A0 void g(int arg_0) { data_=
-&gt;op_3(std::move(arg_0)); }</div><div class=3D"subprettyprint"><br></div=
><div class=3D"subprettyprint">=C2=A0private:</div><div class=3D"subprettyp=
rint">=C2=A0 class Abstraction {</div><div class=3D"subprettyprint">=C2=A0 =
=C2=A0public:</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 virtual Foo =
op_0() =3D 0;</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 virtual void=
 op_1() =3D 0;</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 virtual Foo=
 op_2() =3D 0;</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 virtual voi=
d op_3(int&amp;&amp;) =3D 0;</div><div class=3D"subprettyprint">=C2=A0 =C2=
=A0 virtual ~Abstraction() {}</div><div class=3D"subprettyprint">=C2=A0 };<=
/div><div class=3D"subprettyprint"><br></div><div class=3D"subprettyprint">=
=C2=A0 template &lt;class Data&gt;</div><div class=3D"subprettyprint">=C2=
=A0 class Implementation final : public Abstraction {</div><div class=3D"su=
bprettyprint">=C2=A0 =C2=A0public:</div><div class=3D"subprettyprint">=C2=
=A0 =C2=A0 Implementation(Data&amp;&amp; data) : data_(std::forward&lt;Data=
&gt;(data)) {}</div><div class=3D"subprettyprint">=C2=A0 =C2=A0 Foo op_0() =
override { return Data(data_); }</div><div class=3D"subprettyprint">=C2=A0 =
=C2=A0 void op_1() override { data_(); }</div><div class=3D"subprettyprint"=
>=C2=A0 =C2=A0 Foo op_2() override { return data_.f(); }</div><div class=3D=
"subprettyprint">=C2=A0 =C2=A0 void op_3(int&amp;&amp; arg_0) override { da=
ta_.g(std::forward&lt;int&gt;(arg_0)); }</div><div class=3D"subprettyprint"=
><br></div><div class=3D"subprettyprint">=C2=A0 =C2=A0private:</div><div cl=
ass=3D"subprettyprint">=C2=A0 =C2=A0 Data data_;</div><div class=3D"subpret=
typrint">=C2=A0 };</div><div class=3D"subprettyprint"><br></div><div class=
=3D"subprettyprint">=C2=A0 std::shared_ptr&lt;Abstraction&gt; data_;</div><=
div class=3D"subprettyprint">};</div></font></div></code></div><br><br></di=
v><div><br></div><div><br></div>On Tuesday, May 9, 2017 at 5:27:34 AM UTC+8=
, Barry Revzin wrote:<blockquote class=3D"gmail_quote" style=3D"margin: 0;m=
argin-left: 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;"><blockquo=
te class=3D"gmail_quote" style=3D"margin:0;margin-left:0.8ex;border-left:1p=
x #ccc solid;padding-left:1ex"><div dir=3D"ltr"><blockquote class=3D"gmail_=
quote" style=3D"margin:0;margin-left:0.8ex;border-left:1px #ccc solid;paddi=
ng-left:1ex"><div dir=3D"ltr"><div><div class=3D"gmail_quote"><div>Yep, I t=
hink we are talking about automatic type-erasure here.<br></div><div><br></=
div><div>Sean Parent has done a lot of work with type-erasure and polymorph=
ic values types based on &quot;concepts&quot; (pre Concepts concepts).<br><=
br></div><div>I wonder if Concepts + reflection might allow someone to writ=
e:<br><br></div><div>Foo foo; // foo happens to model Concept<br></div><div=
>std::erased&lt;Concept&gt; efoo =3D foo;<br></div><div>func(efoo);=C2=A0 /=
/ Not a templatized function<br></div><div><br></div><div>Tony<br></div></d=
iv></div></div></blockquote><div><br>That would require lots of things that=
 don&#39;t exist at present:<br><br>1: Reflection to be able to introspect =
concepts, being able to iterate over their constituent expressions.<br><br>=
2: Reflection would need to be able to <i>generate</i> code. Otherwise, `st=
d::erased` wouldn&#39;t be able to generate non-member functions to handle =
non-members of the `Concept`.<br><br>3: Concepts would have to be able to b=
e passed as template parameters.<br></div></div></blockquote><div><br></div=
><div>Yeah, but I&#39;d argue it&#39;s really what you want. Type erasure i=
s extremely useful, Concepts already express the desired interface, so it&#=
39;s really natural to stick them together. It&#39;d be pretty valuable to =
either:</div><div><br></div><div>(1) be able to write a library that works =
like erased&lt;Concept&gt; (e.g. Rust&#39;s Box)</div><div>(2) provide a me=
chanism in the language to implicitly generate such a thing, whether by</di=
v><div>(2a) reappropriating the abbreviated function syntax to do type eras=
ure instead, or=C2=A0</div><div>(2b) providing a new syntax like void foo(C=
oncept^ )=C2=A0</div><div><br></div><div>Any of those approaches requires a=
 lot of stuff that we don&#39;t have today, and won&#39;t have on day 1 on =
any of these TSes hitting, but I think are worth considering longer term as=
 next steps for cool problems to solve with Concepts.</div></blockquote></d=
iv>

<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/d15cc3d3-b526-499d-9b8b-2d4ecd15aba9%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/d15cc3d3-b526-499d-9b8b-2d4ecd15aba9=
%40isocpp.org</a>.<br />

------=_Part_4929_1991480419.1494316908861--

------=_Part_4928_340421383.1494316908861--

.
