220 34181 <3509394f-e995-41d1-8fe0-3e7d8ecfe63e@isocpp.org> article
Path: news.gmane.org!.POSTED!not-for-mail
From: Curious <rmn100@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: Structured bindings with polymorphic lambdas
Date: Mon, 28 Aug 2017 11:14:03 -0700 (PDT)
Lines: 335
Approved: news@gmane.org
Message-ID: <3509394f-e995-41d1-8fe0-3e7d8ecfe63e@isocpp.org>
References: <b8d14aa1-adcb-41d9-8fe8-d70805927161@isocpp.org>
 <8497b31b-7c9d-4334-ac22-0809c958cb93@isocpp.org>
 <15a70d94-e039-4f82-ba01-bde9d3fbacbd@isocpp.org>
 <6b50933d-291b-4b47-8c0c-82c97d9cb406@isocpp.org>
 <348b59eb-c288-482e-a7f4-473d8f1fbfea@isocpp.org>
 <029d244a-cc53-40de-9c2f-59b1bc776c1b@isocpp.org>
 <481b4d44-74e0-4cd3-8141-62d35dea8350@isocpp.org>
 <cfbbbe0f-cace-46ce-977a-ac57b9c3003e@isocpp.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: blaine.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_5076_330578662.1503944043493"
X-Trace: blaine.gmane.org 1503944061 24376 195.159.176.226 (28 Aug 2017 18:14:21 GMT)
X-Complaints-To: usenet@blaine.gmane.org
NNTP-Posting-Date: Mon, 28 Aug 2017 18:14:21 +0000 (UTC)
Cc: rmn100@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCNP5RVE2QIBB3F2SHGQKGQEOFYP2JI@isocpp.org Mon Aug 28 20:14:15 2017
Return-path: <std-proposals+bncBCNP5RVE2QIBB3F2SHGQKGQEOFYP2JI@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-yw0-f200.google.com ([209.85.161.200])
	by blaine.gmane.org with esmtp (Exim 4.84_2)
	(envelope-from <std-proposals+bncBCNP5RVE2QIBB3F2SHGQKGQEOFYP2JI@isocpp.org>)
	id 1dmOXu-000575-CH
	for gclcip-std-proposals@m.gmane.org; Mon, 28 Aug 2017 20:13:58 +0200
Original-Received: by mail-yw0-f200.google.com with SMTP id b64sf4920288ywh.19
        for <gclcip-std-proposals@m.gmane.org>; Mon, 28 Aug 2017 11:14:05 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=isocpp-org.20150623.gappssmtp.com; s=20150623;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe;
        bh=MtpcKxUZE1b1cDcb5rVBzFrSv7/XDwOUJRKg7JP0ynY=;
        b=oOX1bdmvEnkp16votRXlsrWunxeKzm+dDBzIMHo+lGlyO1syOhQ3hIaIogBAcNvFEQ
         LGF/MtREethypUjDXowfu1umEEnR4VS2OJ65IOO2V2OkU/a0YIoxryygb8lEdypIm0z4
         tWiBu1M2XpAW6Rm1XRr6unW8EM05rTMR7ahamo9gy5Bik37bIWWzEVaMUTMzDAnNrW/n
         okZ1A1s83UO9dIqO2kRDiDFubW4W5zq4jz5shRCfnKPOo3oJCWYK2iRXP/Ylf+EC9hGY
         EmwgOkOQvjs2kL8wtd9EMSdRRcRlNhkfdbpNCvOpQYe1m6OxqrKYfmCbRYzlsZSgOvJR
         iMdA==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20161025;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:x-original-sender:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe;
        bh=MtpcKxUZE1b1cDcb5rVBzFrSv7/XDwOUJRKg7JP0ynY=;
        b=OQOJh98XEZxnO9ZwANVHRIS2aQeYdUNncWwznzjTi0YWU4gusyH5K98MT7jPogxC6Y
         XNHRAdlLedijkNom5FwnH6ZkjmAmPHLZ4pEfS9Z2FhbztFv3kigKO2zTBFMnMcT9fRiy
         9Q4EhsVwgsQRIWa/bjvUDtiaUZ6njQTLju7pYdIfUWXeMShH8wgnEtGRf1Xyx61ubOjU
         UkV1EPLF6DCCOWEFDxB5CBdwuxdB1Yne01ui01Hlz1UjXgdFrufBoruMzaGi++tJ2zuu
         iugKf3WZDUskJDT+rwir48OG5kP02c8C6O3ZV9ubHMO0tX3W8bk43KquzAi5Ub7WyvGv
         EUvA==
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:cc: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=MtpcKxUZE1b1cDcb5rVBzFrSv7/XDwOUJRKg7JP0ynY=;
        b=Pio80qz7DOVYVxuAKm1AUxGYhvOmdTsHo3kZrMupHHLjlQQ8ngf6/jwLqg/77dBLd/
         2jzEuJda4yQBfISzasV04BNg+loabzfAILiXEjIbBqXoigzP0chBJayxXRCinHjxTNwR
         Yt/ROtQZ5hsBGLUJHXwGSwV8GqT/s2JVTjwd2/CKBklWohiYQvSbU2PwCKXk/7gJR8cB
         EPJjlLUm5u9RSAwDrKW9d8gTwpBkiIVrTTCTsUlNSQqB3hrtzwY/JGFHFQ1S/O7N9Zcv
         6Wm/9MUYS4HlPqldRQlcgq5R2W7F2v9qQ8fYoLNYkUCE2AxP3Q7UrXX4fORCf030sgxr
         aEbg==
X-Gm-Message-State: AHYfb5iDCdYQLF1Gj6+fzCjSKegfRV/ri9JRliEI7wUZYpH8K7Lf3fUE
	ycKlWq5Dt7po16pT
X-Received: by 10.13.223.78 with SMTP id i75mr966602ywe.231.1503944045020;
        Mon, 28 Aug 2017 11:14:05 -0700 (PDT)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.107.52.132 with SMTP id b126ls706089ioa.41.gmail; Mon, 28 Aug
 2017 11:14:04 -0700 (PDT)
X-Received: by 10.31.155.132 with SMTP id d126mr13664vke.17.1503944043936;
        Mon, 28 Aug 2017 11:14:03 -0700 (PDT)
In-Reply-To: <cfbbbe0f-cace-46ce-977a-ac57b9c3003e@isocpp.org>
X-Original-Sender: rmn100@gmail.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:34181
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/34181>

------=_Part_5076_330578662.1503944043493
Content-Type: multipart/alternative; 
	boundary="----=_Part_5077_124583835.1503944043494"

------=_Part_5077_124583835.1503944043494
Content-Type: text/plain; charset="UTF-8"

@T. C, The is_decomposable trait has the same potential ODR issues as 
std::iterator_traits.  But in retrospect, it's not critical to the proposal 
of adding structured bindings to lambdas.  So maybe it's something that I 
can just entirely leave out, and suggest addition later if this is a big 
issue.

On Monday, 28 August 2017 09:44:47 UTC-7, Curious wrote:
>
> You are right.  This makes me wonder.  Are structured bindings not prone 
> to the same problems?  The structured bindings decomposition checks to see 
> if tuple_size<> is a complete type first, and then go on to check if the 
> class can be decomposed via it's public members.  For example
>
> class Something {
> public:
>     int a;
> };
>
> namespace std {
> template <>
> class tuple_size<Something>;
> } // namespace std
>     
> template <typename SomethingType>
> void foo(SomethingType something) {
>     auto [one] = something;
>     static_cast<void>(one);
> }
>
> void bar(Something something) {
>     foo(something);
> }
>
> /**
>  * Define the tuple shenanigans
>  */
> namespace std {
> template <>
> class tuple_size<Something> : std::integral_constant<int, 1> {};
> template <std::size_t Index>
> class tuple_element<Index, Something> {
>     using type = int;
> }
> template <std::size_t Index>
> int get(Something something) {
>     std::cout << "get(Something)" << std::endl;
>     return something.a;
> }
> } // namespace std
>
> void baz(Something something) {
>     // now expect logging
>     foo(something);
> }
>
> Although I suspect the above isn't an ODR problem because the bindings 
> aren't involved in the template instantiation process.  Although it might 
> be surprising to the user.  
>
> I wonder why a simpler approach wasn't taken, why check for tuple_size<> 
> to be a complete type rather than checking for the existence of a static 
> constexpr value or a std::integral_constant<> typedef within the class? 
>  This can now be a possible change, instead of allowing tuple_size<> to be 
> specialized everywhere.  Make classes that want to pretend to be a tuple 
> have a member typedef or a static constexpr and make tuple_size<> use that 
> typedef in the general case, and don't leave the type undefined (I suspect 
> this will break a lot of code, if people are checking to see if 
> tuple_size<> is a complete type).  For example
>
> class TupleLike {
> public:  
>     using tuple_size_type = std::integral_constant<int, 2>;
> private:
>     std::tuple<int, int> a;
> };
>
> This is much simpler and is not prone to ODR issues.  And now structured 
> bindings can check for the existence of and inspect the tuple_size_type 
> alias within the class.  
>
> And then in the general case tuple_size<> can be defined like 
>
> namespace std {
> template <typename T>
> class tuple_size {
>  static constexpr const auto value = T::tuple_size_type::value;
> };
>
> } // namespace std
>
> The second simpler solution to the is_decomposable problem is to not use 
> the trait at all, and just let the lambda translate to an unconstrained 
> template function in an anonymous class.
>
> Also, to illustrate my question about extent of the check, what should the 
>> following code do? (This is basically GB 20's motivating example.)
>>
>
> Shouldn't this cause a hard error?  std::tuple_size is defined, and when 
> the code tries to use it, it finds out that the specialization is just 
> incorrectly defined.
>

-- 
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/3509394f-e995-41d1-8fe0-3e7d8ecfe63e%40isocpp.org.

------=_Part_5077_124583835.1503944043494
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">@T. C, The <font face=3D"courier new, monospace">is_decomp=
osable</font> trait has the same potential ODR issues as <font face=3D"cour=
ier new, monospace">std::iterator_traits</font><font face=3D"arial, sans-se=
rif">. =C2=A0But in retrospect, it&#39;s not critical to the proposal of ad=
ding structured bindings to lambdas. =C2=A0So maybe it&#39;s something that=
 I can just entirely leave out, and suggest addition later if this is a big=
 issue.</font><div><font face=3D"arial, sans-serif"><br></font>On Monday, 2=
8 August 2017 09:44:47 UTC-7, Curious  wrote:<blockquote class=3D"gmail_quo=
te" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddi=
ng-left: 1ex;"><div dir=3D"ltr">You are right. =C2=A0This makes me wonder. =
=C2=A0Are structured bindings not prone to the same problems? =C2=A0The str=
uctured bindings decomposition checks to see if <font face=3D"courier new, =
monospace">tuple_size&lt;&gt;</font> is a complete type first, and then go =
on to check if the class can be decomposed via it&#39;s public members. =C2=
=A0For example<div><br></div><div><div style=3D"background-color:rgb(250,25=
0,250);border:1px solid rgb(187,187,187);word-wrap:break-word"><code><div><=
span style=3D"color:#008">class</span><span style=3D"color:#000"> </span><s=
pan style=3D"color:#606">Something</span><span style=3D"color:#000"> </span=
><span style=3D"color:#660">{</span><span style=3D"color:#000"><br></span><=
span style=3D"color:#008">public</span><span style=3D"color:#660">:</span><=
span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#00=
8">int</span><span style=3D"color:#000"> a</span><span style=3D"color:#660"=
>;</span><span style=3D"color:#000"><br></span><span style=3D"color:#660">}=
;</span><span style=3D"color:#000"><br><br></span><span style=3D"color:#008=
">namespace</span><span style=3D"color:#000"> std </span><span style=3D"col=
or:#660">{</span><span style=3D"color:#000"><br></span><span style=3D"color=
:#008">template</span><span style=3D"color:#000"> </span><span style=3D"col=
or:#660">&lt;&gt;</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#008">class</span><span style=3D"color:#000"> tuple_size</span><s=
pan style=3D"color:#660">&lt;</span><span style=3D"color:#606">Something</s=
pan><span style=3D"color:#660">&gt;;</span><span style=3D"color:#000"><br><=
/span><span style=3D"color:#660">}</span><span style=3D"color:#000"> </span=
><span style=3D"color:#800">// namespace std</span><span style=3D"color:#00=
0"><br>=C2=A0 =C2=A0 <br></span><span style=3D"color:#008">template</span><=
span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span><sp=
an style=3D"color:#008">typename</span><span style=3D"color:#000"> </span><=
span style=3D"color:#606">SomethingType</span><span style=3D"color:#660">&g=
t;</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">v=
oid</span><span style=3D"color:#000"> foo</span><span style=3D"color:#660">=
(</span><span style=3D"color:#606">SomethingType</span><span style=3D"color=
:#000"> something</span><span style=3D"color:#660">)</span><span style=3D"c=
olor:#000"> </span><span style=3D"color:#660">{</span><span style=3D"color:=
#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">auto</span><span =
style=3D"color:#000"> </span><span style=3D"color:#660">[</span><span style=
=3D"color:#000">one</span><span style=3D"color:#660">]</span><span style=3D=
"color:#000"> </span><span style=3D"color:#660">=3D</span><span style=3D"co=
lor:#000"> something</span><span style=3D"color:#660">;</span><span style=
=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"color:#008">static_=
cast</span><span style=3D"color:#080">&lt;void&gt;</span><span style=3D"col=
or:#660">(</span><span style=3D"color:#000">one</span><span style=3D"color:=
#660">);</span><span style=3D"color:#000"><br></span><span style=3D"color:#=
660">}</span><span style=3D"color:#000"><br><br></span><span style=3D"color=
:#008">void</span><span style=3D"color:#000"> bar</span><span style=3D"colo=
r:#660">(</span><span style=3D"color:#606">Something</span><span style=3D"c=
olor:#000"> something</span><span style=3D"color:#660">)</span><span style=
=3D"color:#000"> </span><span style=3D"color:#660">{</span><span style=3D"c=
olor:#000"><br>=C2=A0 =C2=A0 foo</span><span style=3D"color:#660">(</span><=
span style=3D"color:#000">something</span><span style=3D"color:#660">);</sp=
an><span style=3D"color:#000"><br></span><span style=3D"color:#660">}</span=
><span style=3D"color:#000"><br><br></span><span style=3D"color:#800">/**<b=
r>=C2=A0* Define the tuple </span><span style=3D"color:#800">shenanigans<br=
>=C2=A0*/</span><span style=3D"color:#000"><br></span><span style=3D"color:=
#008">namespace</span><span style=3D"color:#000"> std </span><span style=3D=
"color:#660">{</span><span style=3D"color:#000"><br></span><span style=3D"c=
olor:#008">template</span><span style=3D"color:#000"> </span><span style=3D=
"color:#660">&lt;&gt;</span><span style=3D"color:#000"><br></span><span sty=
le=3D"color:#008">class</span><span style=3D"color:#000"> tuple_size</span>=
<span style=3D"color:#660">&lt;</span><span style=3D"color:#606">Something<=
/span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"> </s=
pan><span style=3D"color:#660">:</span><span style=3D"color:#000"> std</spa=
n><span style=3D"color:#660">::</span><span style=3D"color:#000">integral_c=
onstant</span><span style=3D"color:#660">&lt;</span><span style=3D"color:#0=
08">int</span><span style=3D"color:#660">,</span><span style=3D"color:#000"=
> </span><span style=3D"color:#066">1</span><span style=3D"color:#660">&gt;=
</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{};</s=
pan><span style=3D"color:#000"><br></span><span style=3D"color:#008">templa=
te</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;=
</span><span style=3D"color:#000">std</span><span style=3D"color:#660">::</=
span><span style=3D"color:#000">size_t </span><span style=3D"color:#606">In=
dex</span><span style=3D"color:#660">&gt;</span><span style=3D"color:#000">=
<br></span><span style=3D"color:#008">class</span><span style=3D"color:#000=
"> tuple_element</span><span style=3D"color:#660">&lt;</span><span style=3D=
"color:#606">Index</span><span style=3D"color:#660">,</span><span style=3D"=
color:#000"> </span><span style=3D"color:#606">Something</span><span style=
=3D"color:#660">&gt;</span><span style=3D"color:#000"> </span><span style=
=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span=
><span style=3D"color:#008">using</span><span style=3D"color:#000"> type </=
span><span style=3D"color:#660">=3D</span><span style=3D"color:#000"> </spa=
n><span style=3D"color:#008">int</span><span style=3D"color:#660">;</span><=
span style=3D"color:#000"><br></span><span style=3D"color:#660">}</span><sp=
an style=3D"color:#000"><br></span><span style=3D"color:#008">template</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;</span>=
<span style=3D"color:#000">std</span><span style=3D"color:#660">::</span><s=
pan style=3D"color:#000">size_t </span><span style=3D"color:#606">Index</sp=
an><span style=3D"color:#660">&gt;</span><span style=3D"color:#000"><br></s=
pan><span style=3D"color:#008">int</span><span style=3D"color:#000"> </span=
><span style=3D"color:#008">get</span><span style=3D"color:#660">(</span><s=
pan style=3D"color:#606">Something</span><span style=3D"color:#000"> someth=
ing</span><span style=3D"color:#660">)</span><span style=3D"color:#000"> </=
span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br>=C2=
=A0 =C2=A0 std</span><span style=3D"color:#660">::</span><span style=3D"col=
or:#000">cout </span><span style=3D"color:#660">&lt;&lt;</span><span style=
=3D"color:#000"> </span><span style=3D"color:#080">&quot;get(Something)&quo=
t;</span><span style=3D"color:#000"> </span><span style=3D"color:#660">&lt;=
&lt;</span><span style=3D"color:#000"> std</span><span style=3D"color:#660"=
>::</span><span style=3D"color:#000">endl</span><span style=3D"color:#660">=
;</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"=
color:#008">return</span><span style=3D"color:#000"> something</span><span =
style=3D"color:#660">.</span><span style=3D"color:#000">a</span><span style=
=3D"color:#660">;</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#660">}</span><span style=3D"color:#000"><br></span><span style=
=3D"color:#660">}</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#800">// namespace std</span><span style=3D"color:#000"><br><br></span=
><span style=3D"color:#008">void</span><span style=3D"color:#000"> baz</spa=
n><span style=3D"color:#660">(</span><span style=3D"color:#606">Something</=
span><span style=3D"color:#000"> something</span><span style=3D"color:#660"=
>)</span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</s=
pan><span style=3D"color:#000"><br>=C2=A0 =C2=A0 </span><span style=3D"colo=
r:#800">// now expect logging</span><span style=3D"color:#000"><br>=C2=A0 =
=C2=A0 foo</span><span style=3D"color:#660">(</span><span style=3D"color:#0=
00">something</span><span style=3D"color:#660">);</span><span style=3D"colo=
r:#000"><br></span><span style=3D"color:#660">}</span><span style=3D"color:=
#000"><br></span></div></code></div><div><br></div><div>Although I suspect =
the above isn&#39;t an ODR problem because the bindings aren&#39;t involved=
 in the template instantiation process. =C2=A0Although it might be surprisi=
ng to the user. =C2=A0</div><div><br></div><div>I wonder why a simpler appr=
oach wasn&#39;t taken, why check for tuple_size&lt;&gt; to be a complete ty=
pe rather than checking for the existence of a static constexpr value or a =
std::integral_constant&lt;&gt; typedef within the class? =C2=A0This can now=
 be a possible change, instead of allowing tuple_size&lt;&gt; to be special=
ized everywhere. =C2=A0Make classes that want to pretend to be a tuple have=
 a member typedef or a static constexpr and make tuple_size&lt;&gt; use tha=
t typedef in the general case, and don&#39;t leave the type undefined (I su=
spect this will break a lot of code, if people are checking to see if tuple=
_size&lt;&gt; is a complete type). =C2=A0For example</div><div><br></div><d=
iv style=3D"background-color:rgb(250,250,250);border:1px solid rgb(187,187,=
187);word-wrap:break-word"><code><div><span style=3D"color:#008">class</spa=
n><span style=3D"color:#000"> </span><span style=3D"color:#606">TupleLike</=
span><span style=3D"color:#000"> </span><span style=3D"color:#660">{</span>=
<span style=3D"color:#000"><br></span><span style=3D"color:#008">public</sp=
an><span style=3D"color:#660">:</span><span style=3D"color:#000"> =C2=A0<br=
>=C2=A0 =C2=A0 </span><span style=3D"color:#008">using</span><span style=3D=
"color:#000"> tuple_size_type </span><span style=3D"color:#660">=3D</span><=
span style=3D"color:#000"> std</span><span style=3D"color:#660">::</span><s=
pan style=3D"color:#000">integral_constant</span><span style=3D"color:#660"=
>&lt;</span><span style=3D"color:#008">int</span><span style=3D"color:#660"=
>,</span><span style=3D"color:#000"> </span><span style=3D"color:#066">2</s=
pan><span style=3D"color:#660">&gt;;</span><span style=3D"color:#000"><br><=
/span><span style=3D"color:#008">private</span><span style=3D"color:#660">:=
</span><span style=3D"color:#000"><br>=C2=A0 =C2=A0 std</span><span style=
=3D"color:#660">::</span><span style=3D"color:#000">tuple</span><span style=
=3D"color:#660">&lt;</span><span style=3D"color:#008">int</span><span style=
=3D"color:#660">,</span><span style=3D"color:#000"> </span><span style=3D"c=
olor:#008">int</span><span style=3D"color:#660">&gt;</span><span style=3D"c=
olor:#000"> a</span><span style=3D"color:#660">;</span><span style=3D"color=
:#000"><br></span><span style=3D"color:#660">};</span></div></code></div><d=
iv><br></div><div>This is much simpler and is not prone to ODR issues. =C2=
=A0And now structured bindings can check for the existence of and inspect t=
he <font face=3D"courier new, monospace">tuple_size_type</font> alias withi=
n the class. =C2=A0</div><div><br></div><div>And then in the general case <=
font face=3D"courier new, monospace">tuple_size&lt;&gt;</font> can be defin=
ed like=C2=A0</div><div><br></div><div style=3D"background-color:rgb(250,25=
0,250);border:1px solid rgb(187,187,187);word-wrap:break-word"><code><div><=
span style=3D"color:#008">namespace</span><span style=3D"color:#000"> std <=
/span><span style=3D"color:#660">{</span><span style=3D"color:#000"><br></s=
pan><span style=3D"color:#008">template</span><span style=3D"color:#000"> <=
/span><span style=3D"color:#660">&lt;</span><span style=3D"color:#008">type=
name</span><span style=3D"color:#000"> T</span><span style=3D"color:#660">&=
gt;</span><span style=3D"color:#000"><br></span><span style=3D"color:#008">=
class</span><span style=3D"color:#000"> tuple_size </span><span style=3D"co=
lor:#660">{</span><span style=3D"color:#000"><br>=C2=A0</span><span style=
=3D"color:#008">static</span><span style=3D"color:#000"> </span><span style=
=3D"color:#008">constexpr</span><span style=3D"color:#000"> </span><span st=
yle=3D"color:#008">const</span><span style=3D"color:#000"> </span><span sty=
le=3D"color:#008">auto</span><span style=3D"color:#000"> value </span><span=
 style=3D"color:#660">=3D</span><span style=3D"color:#000"> T</span><span s=
tyle=3D"color:#660">::</span><span style=3D"color:#000">tuple_size_type</sp=
an><span style=3D"color:#660">::</span><span style=3D"color:#000">value</sp=
an><span style=3D"color:#660">;</span><span style=3D"color:#000"><br></span=
><span style=3D"color:#660">};</span><span style=3D"color:#000"><br><br></s=
pan><span style=3D"color:#660">}</span><span style=3D"color:#000"> </span><=
span style=3D"color:#800">// namespace std</span><span style=3D"color:#000"=
><br></span></div></code></div><div><br>The second simpler solution to the =
<font face=3D"courier new, monospace">is_decomposable</font> problem is to =
not use the trait at all, and just let the lambda translate to an unconstra=
ined template function in an anonymous class.</div><div><br></div><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"><div>Also, to illustrate my=
 question about extent of the check, what should the following code do? (Th=
is is basically GB 20&#39;s motivating example.)</div></div></blockquote><d=
iv><br></div><div>Shouldn&#39;t this cause a hard error? =C2=A0<font face=
=3D"courier new, monospace">std::tuple_size</font> is defined, and when the=
 code tries to use it, it finds out that the specialization is just incorre=
ctly defined.</div></div></div></blockquote></div></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/3509394f-e995-41d1-8fe0-3e7d8ecfe63e%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/3509394f-e995-41d1-8fe0-3e7d8ecfe63e=
%40isocpp.org</a>.<br />

------=_Part_5077_124583835.1503944043494--

------=_Part_5076_330578662.1503944043493--

.
