220 23861 <6ad65a24-8a2e-4053-b9c9-80d296d98e7d@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Nicol Bolas <jmckesson@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: RFC: Unpacking tuples to value sequences
Date: Tue, 19 Jan 2016 11:15:10 -0800 (PST)
Lines: 357
Approved: news@gmane.org
Message-ID: <6ad65a24-8a2e-4053-b9c9-80d296d98e7d@isocpp.org>
References: <n7jlvp$c44$1@ger.gmane.org> <f758483a-568d-4444-957f-41535c39be4e@isocpp.org> <c91a2d40-17da-4edc-b14b-4e166e9ecaeb@isocpp.org> <6f3ece34-e302-4d95-afd0-4c1924e8a780@isocpp.org> <n7locq$q98$1@ger.gmane.org> <e4a9f750-0608-47ac-9d91-f1201b016b99@isocpp.org>
 <n7lqmm$2d3$1@ger.gmane.org>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/mixed; 
	boundary="----=_Part_1014_1685240265.1453230910971"
X-Trace: ger.gmane.org 1453230920 32766 80.91.229.3 (19 Jan 2016 19:15:20 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Tue, 19 Jan 2016 19:15:20 +0000 (UTC)
Cc: mwoehlke.floss@gmail.com
To: ISO C++ Standard - Future Proposals <std-proposals@isocpp.org>
Original-X-From: std-proposals+bncBCEKFTV6ZUMBBQEW7K2AKGQE6MBUPJQ@isocpp.org Tue Jan 19 20:15:19 2016
Return-path: <std-proposals+bncBCEKFTV6ZUMBBQEW7K2AKGQE6MBUPJQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-yk0-f199.google.com ([209.85.160.199])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBCEKFTV6ZUMBBQEW7K2AKGQE6MBUPJQ@isocpp.org>)
	id 1aLbkI-0006JJ-EM
	for gclcip-std-proposals@m.gmane.org; Tue, 19 Jan 2016 20:15:14 +0100
Original-Received: by mail-yk0-f199.google.com with SMTP id y10sf954753192ykf.2
        for <gclcip-std-proposals@m.gmane.org>; Tue, 19 Jan 2016 11:15:14 -0800 (PST)
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:content-type: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=QOIvcoey8tV2c/4H8DeB0383nQ3OMJG6dIN93UTQlz4=;
        b=Sr0AXnd54KUzszqur03/Qyx4pGwu/ePEPhhF36n3HGg1g//ycsipNgIK35L3B6vSO+
         6L6MFG/VRTRVqAR4WQZnRZ6nc8dF2b2UkAhduoVo1uNjtnR8mrPtvDnbCaIrFtylHEzB
         VqkrHlQ7t+zSzRSNsDtqC2BK8qQalecWGcEan9Wrs2GBjdGQJCrN3LdGaj7aZFuxiYrD
         oMW/6TrcQvERYZ5NGn+6CAR817ge85QoEfJiqx7zTeg/s7ak1t0OMaRZ/c/lBA6L5YL4
         r6QZwp80xaKwbHLacf5jdBYfefp9E2qLSkFfgrRXwvSgp8+8o/1kiBdlWdCWMJg9U0Yk
         Wq7w==
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:cc:message-id:in-reply-to:references:subject
         :mime-version:content-type: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=QOIvcoey8tV2c/4H8DeB0383nQ3OMJG6dIN93UTQlz4=;
        b=KpSli6V/occyTQhjuIbA/1m9JisMGjODjuR4VUCVU6ohzk+CW3pybdIBOjk29XyraH
         yLdiahi52vQgiO6aW9nOYNmyS/qkBQaRQjprOJi4DLJBu3kUv5awuX1jJYZLfB1+DjAP
         JDH/Y6dxaUAKdBfV93RsCwFMv0P57VGO825C2+lHGrKeqBFP0KOcvsyBRvyqM8Bcc9un
         CgWlq4LrwwD/y7+w9LHL1tyOvevcYzlCr8lhYv4HXW2Pwg5Fr/xJSlBUM3LFEbq9RnM3
         cRjk/hJVMuG63rcin+5XvqKVBTx43t6CG4faudQ++SAPs199Fo8tnMOf7bC9ED+A/7DV
         Lvzg==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:cc:message-id:in-reply-to
         :references:subject:mime-version:content-type: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=QOIvcoey8tV2c/4H8DeB0383nQ3OMJG6dIN93UTQlz4=;
        b=R97hQlllYHjAu/I540LBbDfrY0eOywDyDMG0/UXa6iU/BREyAo/jZxj3rsQeeFqA01
         HcqBQ6nPj7s8TKu8Nuf9ZsRTUjtQ6BAOGnp7ePe9jOdfK2EyMpnoeIBDNbA8O5D5ZBB6
         V046jwvZ9+Qq1KC0HqBea75PtWkO+2pXQisRSpeDje7yMoFmGCPGqZlTrN06nVW5oSL1
         JowGofsU7iRBVHufOrbokSLGVMfZgOVfw1uhKWtLbhA3mFc5GwLn1SDYT/tf36HnOuLn
         EpJSU1ixduXqQAz30NQZNYtTAXiuULHDOCIARmnS6JfB9w8UARgrgTio5II3k41IqLkM
         wdYw==
X-Gm-Message-State: ALoCoQnxj+0QdHVIdWOoW/zpqTk4tXIn4JGlvKoRd82UfTcLUx0x5KiV3vy4ZF4U7fsa8CDsDDMSdx8QLCMCZcUa+P0qyHMBOg==
X-Received: by 10.129.134.135 with SMTP id w129mr29396798ywf.24.1453230913232;
        Tue, 19 Jan 2016 11:15:13 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.107.18.137 with SMTP id 9ls1625286ios.106.gmail; Tue, 19 Jan
 2016 11:15:12 -0800 (PST)
X-Received: by 10.50.73.200 with SMTP id n8mr392556igv.6.1453230912152;
        Tue, 19 Jan 2016 11:15:12 -0800 (PST)
In-Reply-To: <n7lqmm$2d3$1@ger.gmane.org>
X-Original-Sender: jmckesson@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:23861
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/23861>

------=_Part_1014_1685240265.1453230910971
Content-Type: multipart/alternative; 
	boundary="----=_Part_1015_312115754.1453230910972"

------=_Part_1015_312115754.1453230910972
Content-Type: text/plain; charset=UTF-8

On Tuesday, January 19, 2016 at 12:11:03 PM UTC-5, Matthew Woehlke wrote:
>
> On 2016-01-19 11:44, Nicol Bolas wrote: 
> > On Tuesday, January 19, 2016 at 11:31:31 AM UTC-5, Matthew Woehlke 
> wrote: 
> >> On 2016-01-19 10:40, Nicol Bolas wrote: 
> >>> auto ...thing1 = func([*]f, [*]g)...; 
> >> 
> >> I alluded to this in my other reply, but I think it bears repeating... 
> >> what does this (RHS) mean? 
> >> 
> >>   - { func(f<0>, g<0>), func(f<1>, g<1>) } 
> >>   - { func(f<0>, f<1>, g<0>), func(f<0>, f<1>, g<1>) } 
> >>   - { func(f<0>, g<0>, g<1>), func(f<1>, g<0>, g<1>) } 
> >>   - func(f<0>, f<1>, g<0>, g<1>) 
> >> 
> >> I could legitimately want *any* of those. 
> > 
> > And my syntax can provide *all* of them: 
> > 
> > func([*]f, [*]g)...; 
> > func([*]f..., [*]g)...; 
> > func([*]f, [*]g...)...; 
> > func([*]f..., [*]g...); 
>
> Why do I have to unpack it *twice*? Ugh... 
>

Because that's *what you're doing*. Take the second case. You want to 
unpack `f` within the argument list. But you want to unpack `g` *across* 
`func`. That's two separate unpack steps, so it needs two separate unpack 
operations.

Your mechanism is too simplified to be of *general* use. There are 
legitimate reasons for people to use all of these forms, and your 
particular use case(s) are not sufficiently important to force users to 
resort to arbitrary other methods to get them.

We'd be better off with *no* unpacking syntax than with a half-baked one.

> [...] lots and lots of heinous syntax. 
>
> I find your proposal much too complicated and severely lacking in 
> rationale why we need such as a *language* feature. (I have yet to see 
> you offer a rationale, besides "hey, wouldn't it be great if...".)


.... The *only part* of your proposal that absolutely needs to be a 
*language* feature is the ability to unpack a tuple into a 
braced-init-list. You could always create a variadic version of `apply` 
that walks through the argument list and unpacks any tuples it sees. So the 
only place in your proposal that absolutely needs it to be a part of the 
language is braced-init-lists.

So if we're going by what absolutely cannot possibly be done without a 
language feature, then your proposal is really no more motivated than mine. 
Since mine also includes that, but much more.

Furthermore, if that were the standard by which features were approved, we 
wouldn't have lambdas. Because there is nothing there that couldn't be done 
with structs declared within the function. In-function structs couldn't 
participate in template deduction in C++03, which is why they couldn't have 
been used in many cases. So technically, all C++11 *had* to do was allow 
them to participate like any other type. And in fact, the committee did 
this. Yet they still provided lambdas anyway. Why?

Because it's a highly useful feature for a wide variety of circumstances 
that makes code so much easier to write. Same goes for range-for and many 
other things.

And if we continue with your logic, we should only have allowed `...` to be 
applied to the pack itself, rather than to expression "patterns". After 
all, we could always find ways to metaprogram around unpacking patterns. No 
need to create confusion if you want to do `func(args)...` to call the 
function multiple times with each argument. No, we clearly should have made 
people say `broadcast(func, args...)` instead.

Yet we didn't. We allowed `...` to expand almost any expression. Why?

Because it was *exceptionally useful*.

So clearly the standard for what should be a language feature is not merely 
"things that* cannot* be a library feature."

However, if you really want something that absolutely must be a language 
feature, there's this: efficiency.

In a different post, I pointed out this use case:

auto test4 = make_tuple(func([*]rev_agg, pack)...);

Where `pack` is a function parameter pack. This calls `func` for each pair 
of values, capturing them in a tuple.

And you said you could do it under your syntax with:

auto zipped = std::zip(rev_agg, make_tuple(pack...));
auto test4 =
  std::apply_each([](auto pair){ return func([*]pair); }, zipped);

So, step 1 is to take the elements of the function parameter pack and make 
a tuple out of them. Well, that's going to copy/move some of them into a 
temporary. Then, we create a tuple of pairs of those values, which 
copy/moves them again. It *also* copies out of `rev_agg` for no reason. The 
temporary is then destroyed.

Or you can do what I said, which will always boil down to the most 
efficient code. No temporaries are created. It's just a sequence of `get<>` 
calls.

Oh, and proper argument forwarding can be used:

auto test4 = make_tuple(func([*]rev_agg, forward<Args>(pack))...);

Even if you change your version to use `forward_as_tuple`, you're still 
using copying out of `rev_agg`. Whereas mine just uses `get<I>` directly in 
situ. No pointless lambdas, no zipping or copying. It boils down to exactly 
what you want and no more.

In the best possible case, where `zip` returns a tuple of references (which 
kinda breaks `forward_as_tuple`), you're still creating a needless 
temporary, which takes up unnecessary room on the stack.

Your way costs both memory and runtime performance. Mine does not. Mine 
doesn't make you pay for something you don't have to.

Oh, and the temporary in this case must be named. Weren't you one of those 
who were saying that naming things is hard, that it's a cost we have to 
pay, so we should be able to return unnamed types ;) (note: I'm not against 
the temporary because it's named. I'm against it because it's taking up 
space and performance. The name is irrelevant to me).

As 
> such, I cannot support it in good conscience, and so I will reiterate my 
> earlier comment: If you feel strongly, I recommend that you write and 
> present a competing paper. 
>
> Unless you can provide a better justification, at this time I intend to 
> continue with my version in its current form. 
>

-- 

--- 
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
Visit this group at https://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_1015_312115754.1453230910972
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

On Tuesday, January 19, 2016 at 12:11:03 PM UTC-5, Matthew Woehlke wrote:<b=
lockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;borde=
r-left: 1px #ccc solid;padding-left: 1ex;">On 2016-01-19 11:44, Nicol Bolas=
 wrote:
<br>&gt; On Tuesday, January 19, 2016 at 11:31:31 AM UTC-5, Matthew Woehlke=
 wrote:
<br>&gt;&gt; On 2016-01-19 10:40, Nicol Bolas wrote:=20
<br>&gt;&gt;&gt; auto ...thing1 =3D func([*]f, [*]g)...;=20
<br>&gt;&gt;
<br>&gt;&gt; I alluded to this in my other reply, but I think it bears repe=
ating...=20
<br>&gt;&gt; what does this (RHS) mean?=20
<br>&gt;&gt;
<br>&gt;&gt; =C2=A0 - { func(f&lt;0&gt;, g&lt;0&gt;), func(f&lt;1&gt;, g&lt=
;1&gt;) }=20
<br>&gt;&gt; =C2=A0 - { func(f&lt;0&gt;, f&lt;1&gt;, g&lt;0&gt;), func(f&lt=
;0&gt;, f&lt;1&gt;, g&lt;1&gt;) }=20
<br>&gt;&gt; =C2=A0 - { func(f&lt;0&gt;, g&lt;0&gt;, g&lt;1&gt;), func(f&lt=
;1&gt;, g&lt;0&gt;, g&lt;1&gt;) }=20
<br>&gt;&gt; =C2=A0 - func(f&lt;0&gt;, f&lt;1&gt;, g&lt;0&gt;, g&lt;1&gt;)=
=20
<br>&gt;&gt;=20
<br>&gt;&gt; I could legitimately want *any* of those.
<br>&gt;=20
<br>&gt; And my syntax can provide *all* of them:
<br>&gt;=20
<br>&gt; func([*]f, [*]g)...;
<br>&gt; func([*]f..., [*]g)...;
<br>&gt; func([*]f, [*]g...)...;
<br>&gt; func([*]f..., [*]g...);
<br>
<br>Why do I have to unpack it *twice*? Ugh...
<br></blockquote><div><br>Because that&#39;s <i>what you&#39;re doing</i>. =
Take the second case. You want to unpack `f` within the argument list. But =
you want to unpack `g` <i>across</i> `func`. That&#39;s two separate unpack=
 steps, so it needs two separate unpack operations.<br><br>Your mechanism i=
s too simplified to be of <i>general</i> use. There are legitimate reasons =
for people to use all of these forms, and your particular use case(s) are n=
ot sufficiently important to force users to resort to arbitrary other metho=
ds to get them.<br><br>We&#39;d be better off with <i>no</i> unpacking synt=
ax than with a half-baked one.<br><br></div><blockquote class=3D"gmail_quot=
e" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;paddin=
g-left: 1ex;">
&gt; [...] lots and lots of heinous syntax.
<br>
<br>I find your proposal much too complicated and severely lacking in
<br>rationale why we need such as a *language* feature. (I have yet to see
<br>you offer a rationale, besides &quot;hey, wouldn&#39;t it be great if..=
..&quot;.)</blockquote><div><br>... The <i>only part</i> of your proposal th=
at absolutely needs to be a *language* feature is the ability to unpack a t=
uple into a braced-init-list. You could always create a variadic version of=
 `apply` that walks through the argument list and unpacks any tuples it see=
s. So the only place in your proposal that absolutely needs it to be a part=
 of the language is braced-init-lists.<br><br>So if we&#39;re going by what=
 absolutely cannot possibly be done without a language feature, then your p=
roposal is really no more motivated than mine. Since mine also includes tha=
t, but much more.<br><br>Furthermore, if that were the standard by which fe=
atures were approved, we wouldn&#39;t have lambdas. Because there is nothin=
g there that couldn&#39;t be done with structs declared within the function=
.. In-function structs couldn&#39;t participate in template deduction in C++=
03, which is why they couldn&#39;t have been used in many cases. So technic=
ally, all C++11 <i>had</i> to do was allow them to participate like any oth=
er type. And in fact, the committee did this. Yet they still provided lambd=
as anyway. Why?<br><br>Because it&#39;s a highly useful feature for a wide =
variety of circumstances that makes code so much easier to write. Same goes=
 for range-for and many other things.<br><br>And if we continue with your l=
ogic, we should only have allowed `...` to be applied to the pack itself, r=
ather than to expression &quot;patterns&quot;. After all, we could always f=
ind ways to metaprogram around unpacking patterns. No need to create confus=
ion if you want to do `func(args)...` to call the function multiple times w=
ith each argument. No, we clearly should have made people say `broadcast(fu=
nc, args...)` instead.<br><br>Yet we didn&#39;t. We allowed `...` to expand=
 almost any expression. Why?<br><br>Because it was <i>exceptionally useful<=
/i>.<br><br>So clearly the standard for what should be a language feature i=
s not merely &quot;things that<i> cannot</i> be a library feature.&quot;<br=
><br>However, if you really want something that absolutely must be a langua=
ge feature, there&#39;s this: efficiency.<br><br>In a different post, I poi=
nted out this use case:<br><br><div class=3D"prettyprint" style=3D"backgrou=
nd-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-styl=
e: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prettyp=
rint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D"s=
tyled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-=
by-prettify"> test4 </span><span style=3D"color: #660;" class=3D"styled-by-=
prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettif=
y"> make_tuple</span><span style=3D"color: #660;" class=3D"styled-by-pretti=
fy">(</span><span style=3D"color: #000;" class=3D"styled-by-prettify">func<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">([*]</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify">rev_agg</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> pack</span><span style=3D"c=
olor: #660;" class=3D"styled-by-prettify">)...);</span></div></code></div><=
br>Where `pack` is a function parameter pack. This calls `func` for each pa=
ir of values, capturing them in a tuple.<br><br>And you said you could do i=
t under your syntax with:<br><br><div class=3D"prettyprint" style=3D"backgr=
ound-color: rgb(250, 250, 250); border-color: rgb(187, 187, 187); border-st=
yle: solid; border-width: 1px; word-wrap: break-word;"><code class=3D"prett=
yprint"><div class=3D"subprettyprint"><span style=3D"color: #008;" class=3D=
"styled-by-prettify">auto</span><span style=3D"color: #000;" class=3D"style=
d-by-prettify"> zipped </span><span style=3D"color: #660;" class=3D"styled-=
by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pret=
tify"> std</span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">zip</spa=
n><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><span s=
tyle=3D"color: #000;" class=3D"styled-by-prettify">rev_agg</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> make_tuple</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">(</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify">pack</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">...));</span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"><br></span><span style=3D"color: #008;" class=3D"style=
d-by-prettify">auto</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> test4 </span><span style=3D"color: #660;" class=3D"styled-by-pret=
tify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"><=
br>=C2=A0 std</span><span style=3D"color: #660;" class=3D"styled-by-prettif=
y">::</span><span style=3D"color: #000;" class=3D"styled-by-prettify">apply=
_each</span><span style=3D"color: #660;" class=3D"styled-by-prettify">([](<=
/span><span style=3D"color: #008;" class=3D"styled-by-prettify">auto</span>=
<span style=3D"color: #000;" class=3D"styled-by-prettify"> pair</span><span=
 style=3D"color: #660;" class=3D"styled-by-prettify">){</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=3D"color=
: #008;" class=3D"styled-by-prettify">return</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> func</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">([*]</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify">pair</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">);</span><span style=3D"color: #000;" class=3D"styled-by-=
prettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify"=
>},</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> zipped=
</span><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><=
/div></code></div><br> So, step 1 is to take the elements of the function p=
arameter pack and make a tuple out of them. Well, that&#39;s going to copy/=
move some of them into a temporary. Then, we create a tuple of pairs of tho=
se values, which copy/moves them again. It <i>also</i> copies out of `rev_a=
gg` for no reason. The temporary is then destroyed.<br><br>Or you can do wh=
at I said, which will always boil down to the most efficient code. No tempo=
raries are created. It&#39;s just a sequence of `get&lt;&gt;` calls.<br><br=
>Oh, and proper argument forwarding can be used:<br><br><div class=3D"prett=
yprint" style=3D"background-color: rgb(250, 250, 250); border-color: rgb(18=
7, 187, 187); border-style: solid; border-width: 1px; word-wrap: break-word=
;"><code class=3D"prettyprint"><div class=3D"subprettyprint"><span style=3D=
"color: #008;" class=3D"styled-by-prettify">auto</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> test4 </span><span style=3D"color: #=
660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #000;" c=
lass=3D"styled-by-prettify"> make_tuple</span><span style=3D"color: #660;" =
class=3D"styled-by-prettify">(</span><span style=3D"color: #000;" class=3D"=
styled-by-prettify">func</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">([*]</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify">rev_agg</span><span style=3D"color: #660;" class=3D"styled-by-prett=
ify">,</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> for=
ward</span><span style=3D"color: #660;" class=3D"styled-by-prettify">&lt;</=
span><span style=3D"color: #606;" class=3D"styled-by-prettify">Args</span><=
span style=3D"color: #660;" class=3D"styled-by-prettify">&gt;(</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify">pack</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">))...);</span></div></code><=
/div><br>Even if you change your version to use `forward_as_tuple`, you&#39=
;re still using copying out of `rev_agg`. Whereas mine just uses `get&lt;I&=
gt;` directly in situ. No pointless lambdas, no zipping or copying. It boil=
s down to exactly what you want and no more.<br><br>In the best possible ca=
se, where `zip` returns a tuple of references=20
(which kinda breaks `forward_as_tuple`), you&#39;re still creating a=20
needless temporary, which takes up unnecessary room on the stack.<br><br>Yo=
ur way costs both memory and runtime performance. Mine does not. Mine doesn=
&#39;t make you pay for something you don&#39;t have to.<br><br>Oh, and the=
 temporary in this case must be named. Weren&#39;t you one of those who wer=
e saying that naming things is hard, that it&#39;s a cost we have to pay, s=
o we should be able to return unnamed types ;) (note: I&#39;m not against t=
he temporary because it&#39;s named. I&#39;m against it because it&#39;s ta=
king up space and performance. The name is irrelevant to me).<br><br></div>=
<blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;bor=
der-left: 1px #ccc solid;padding-left: 1ex;">As
<br>such, I cannot support it in good conscience, and so I will reiterate m=
y
<br>earlier comment: If you feel strongly, I recommend that you write and
<br>present a competing paper.
<br>
<br>Unless you can provide a better justification, at this time I intend to
<br>continue with my version in its current form.
<br></blockquote>

<p></p>

-- <br />
<br />
--- <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 />
Visit this group at <a href=3D"https://groups.google.com/a/isocpp.org/group=
/std-proposals/">https://groups.google.com/a/isocpp.org/group/std-proposals=
/</a>.<br />

------=_Part_1015_312115754.1453230910972--
------=_Part_1014_1685240265.1453230910971--

.
