Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Lambdas and variadic templates

3 views
Skip to first unread message

Sergey S.

unread,
Dec 9, 2009, 1:51:54 AM12/9/09
to
Hello.

Should lambdas capture parameters packs? Due to parts 5.1.2
(expr.prim.lambda) and 14.6.3 (temp.variadic) there is no way to make
pack expansion within lambda function definition. These code samples:

template<typename Op, typename ... F>
function<double (double)> DoOperator(Op op, F ... fs)
{
return [=](double x) -> double {return op(fs(x)...);};
}

and

template<typename Op, typename ... F>
function<double (double)> DoOperator(Op op, F ... fs)
{
return [op, fs...](double x) -> double {return op(fs(x)...);};
}

are not allowed by the current working draft. Is there any significant
reason to to disallow such expansion or this is just an issue?

Second question. Is pack expansions contexts list in clause 4 of
14.6.3 exhaustive? If this list is exhaustive why it doesn't contain
function call context which is demonstrated in the example for this
clause?


--
Best Regards,
Sergey mailto:flex_...@artberg.ru

--
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@netlab.cs.rpi.edu]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html ]

Johannes Schaub (litb)

unread,
Dec 9, 2009, 1:08:22 PM12/9/09
to
Sergey S. wrote:

> Hello.
>
> [snipped]


> Second question. Is pack expansions contexts list in clause 4 of
> 14.6.3 exhaustive? If this list is exhaustive why it doesn't contain
> function call context which is demonstrated in the example for this
> clause?
>

The list seems to be exhaustive. In the function call context "f(&rest...)",
the pack expansion occurs in an initializer-list.

Peter Bright

unread,
Dec 9, 2009, 1:07:48 PM12/9/09
to
On Dec 9, 6:51 am, "Sergey S." <flex_fer...@artberg.ru> wrote:
> Second question. Is pack expansions contexts list in clause 4 of
> 14.6.3 exhaustive? If this list is exhaustive why it doesn't contain
> function call context which is demonstrated in the example for this
> clause?
This apparent omission is one of the things I noticed (
http://groups.google.com/group/comp.std.c++/browse_frm/thread/f72e3ff17d85c092#
) when I tried to do something with them. It must surely be a
permitted context (the examples in the draft use it in such a way, and
the motivating example of things like printf use it in such a way),
but it doesn't seem to actually say so.

Personally I would like the permitted expansion contexts to be
extended to e.g. do/while loop conditions (joined by &&) and arbitrary
statements (joined by ;). It would make using the packs a lot more
natural.

Mathias Gaunard

unread,
Dec 10, 2009, 12:31:24 PM12/10/09
to
On 9 d�c, 06:51, "Sergey S." <flex_fer...@artberg.ru> wrote:
> Hello.
>
> Should lambdas capture parameters packs?

Wouldn't that make them parametric, and thus polymorphic?
The paper explicitly says it only supports monomorphic lambdas.

Nikolay Ivchenkov

unread,
Dec 10, 2009, 12:31:08 PM12/10/09
to
On 9 Dec, 21:07, Peter Bright <drpi...@gmail.com> wrote:
> On Dec 9, 6:51 am, "Sergey S." <flex_fer...@artberg.ru> wrote:> Second question. Is pack expansions contexts list in clause 4 of
> > 14.6.3 exhaustive? If this list is exhaustive why it doesn't contain
> > function call context which is demonstrated in the example for this
> > clause?
>
> This apparent omission is one of the things I noticed (http://groups.google.com/group/comp.std.c++/browse_frm/thread/f72e3ff...

> ) when I tried to do something with them. It must surely be a
> permitted context (the examples in the draft use it in such a way, and
> the motivating example of things like printf use it in such a way),
> but it doesn't seem to actually say so.

According to 5.2.2/1, a function call has the form

postfix-expression ( expression-list opt )

expression-list is defined in 5.2/1 as follows:

expression-list:
initializer-list

See 14.6.3/4:

Pack expansions can occur in the following contexts:
� In an initializer-list (8.5); the pattern is an initializer-clause.
[...]

Sergey S.

unread,
Dec 11, 2009, 1:44:09 PM12/11/09
to
Peter Bright <drpi...@gmail.com> wrote:

> Personally I would like the permitted expansion contexts to be
> extended to e.g. do/while loop conditions (joined by &&) and arbitrary
> statements (joined by ;). It would make using the packs a lot more
> natural.

Of course, it would be great. But it is able to reach almost the same
functionality within current VT specification. Just combine 'ignore'
function with 'assignment-expression':

template<typename ... T>
void ignore(T ...) {;}

template<typename ... T>
bool IsPositive(T ... nums)
{
bool ret_val = true;
ignore(ret_val = ret_val && nums >= 0 ...);
}

Unfortunately, such functions can not be constexpr...

Nikolay, thanks. I see.

Peter Bright

unread,
Dec 12, 2009, 9:23:02 PM12/12/09
to
On Dec 10, 5:31 pm, Nikolay Ivchenkov <ts...@mail.ru> wrote:
> On 9 Dec, 21:07, Peter Bright <drpi...@gmail.com> wrote:
>
> > On Dec 9, 6:51 am, "Sergey S." <flex_fer...@artberg.ru> wrote:> Second question. Is pack expansions contexts list in clause 4 of
> > > 14.6.3 exhaustive? If this list is exhaustive why it doesn't contain
> > > function call context which is demonstrated in the example for this
> > > clause?
>
> > This apparent omission is one of the things I noticed (http://groups.google.com/group/comp.std.c++/browse_frm/thread/f72e3ff...
> > ) when I tried to do something with them. It must surely be a
> > permitted context (the examples in the draft use it in such a way, and
> > the motivating example of things like printf use it in such a way),
> > but it doesn't seem to actually say so.
>
> According to 5.2.2/1, a function call has the form
>
> postfix-expression ( expression-list opt )
>
> expression-list is defined in 5.2/1 as follows:
>
> expression-list:
> initializer-list
>
> See 14.6.3/4:
>
> Pack expansions can occur in the following contexts:
> � In an initializer-list (8.5); the pattern is an initializer-clause.
> [...]
>

Ah yes, so I see. I hadn't looked through the grammar fully and
assumed an initializer-list could only be used for initializers,
rather than arbitrary function calls.

Peter Bright

unread,
Dec 12, 2009, 9:23:19 PM12/12/09
to
On Dec 11, 6:44 pm, "Sergey S." <flex_fer...@artberg.ru> wrote:
> Peter Bright <drpi...@gmail.com> wrote:
> > Personally I would like the permitted expansion contexts to be
> > extended to e.g. do/while loop conditions (joined by &&) and arbitrary
> > statements (joined by ;). It would make using the packs a lot more
> > natural.
>
> Of course, it would be great. But it is able to reach almost the same
> functionality within current VT specification. Just combine 'ignore'
> function with 'assignment-expression':
>
> template<typename ... T>
> void ignore(T ...) {;}
>
> template<typename ... T>
> bool IsPositive(T ... nums)
> {
> bool ret_val = true;
> ignore(ret_val = ret_val && nums >= 0 ...);
>
> }
>
> Unfortunately, such functions can not be constexpr...
>

More problematic, IMO, is that this doesn't appear to work for void-
returning functions, presumably because it cannot construct "void
ignore(void, void, void, void)" (etc.).

Sergey S.

unread,
Dec 14, 2009, 12:42:17 PM12/14/09
to
On 13 Dec, 05:23, Peter Bright <drpi...@gmail.com> wrote:

>
> More problematic, IMO, is that this doesn't appear to work for void-
> returning functions, presumably because it cannot construct "void
> ignore(void, void, void, void)" (etc.).

I agree with you. But there is workaround present. Here it is:

template<typename ... T>
void ignore(T ... )
{
;
}

template<typename T1, typename ... A>
int void_wrapper(T1 fn, A ... args)
{
fn(args ...);

return 0;
}

void f(int& x)
{
x += 1;
std::cout << x << " ";
}

template<typename ... T>
int do_something(T ... args)
{
ignore(void_wrapper(f, args)...);

return 0;

0 new messages