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

lambda in template

46 views
Skip to first unread message

Ralf Goertz

unread,
Dec 6, 2016, 8:02:28 AM12/6/16
to
Hi,

is it possible to have a lambda expression as a template argument? If
not why not? I get an error when I try to compile the following

typedef std::set< std::set<int>,
[](const std::set<int>&x,const std::set<int>&y){
return x.size()==y.size() ? x<y : x.size()<y.size();
}> Setset;

error: lambda-expression in template-argument

Background is that I'd rather have sets with fewer elements sorted
before sets with more elements.

Öö Tiib

unread,
Dec 6, 2016, 9:27:07 AM12/6/16
to
On Tuesday, 6 December 2016 15:02:28 UTC+2, Ralf Goertz wrote:
> Hi,
>
> is it possible to have a lambda expression as a template argument?

Probably it is not meant to be possible to have since type of lambda
expression is said to be unspecified and compilers seem to hate
lambda expressions in unevaluated contexts like as arguments of
decltype or sizeof.

> If
> not why not? I get an error when I try to compile the following
>
> typedef std::set< std::set<int>,
> [](const std::set<int>&x,const std::set<int>&y){
> return x.size()==y.size() ? x<y : x.size()<y.size();
> }> Setset;
>
> error: lambda-expression in template-argument

That is different issue. Lambda expression is not type, it is
value of unspecified type. Learn to use std::set with
comparator:

auto comp = [](int x, int y){ return x < y; };
auto set = std::set<int,decltype(comp)>( comp );>

> Background is that I'd rather have sets with fewer elements sorted
> before sets with more elements.

That background was kinda whoosh for me.

Ralf Goertz

unread,
Dec 6, 2016, 9:42:22 AM12/6/16
to
Am Tue, 6 Dec 2016 06:26:59 -0800 (PST)
schrieb Öö Tiib <oot...@hot.ee>:

> That is different issue. Lambda expression is not type, it is value of
> unspecified type. Learn to use std::set with comparator:
>
> auto comp = [](int x, int y){ return x < y; };
> auto set = std::set<int,decltype(comp)>( comp );>

Thanks, The problem with this solution is that I can't use it as
typedef. I don't want to give „comp“ as argument whenever I declare a
variable of that type. But of course I can do it with comp being a class
defining a „bool operator()(…)“

> > Background is that I'd rather have sets with fewer elements sorted
> > before sets with more elements.
>
> That background was kinda whoosh for me.
>

I need sets of sets of int. With defaults I get

{{1,2,5},{3},{3,4}}

But I need them in the order:

{{3},{3,4},{1,2,5}}

Smaller sets before bigger sets.

Ralf Goertz

unread,
Dec 6, 2016, 10:37:58 AM12/6/16
to
Am 6 Dec 2016 15:27:23 GMT
schrieb r...@zedat.fu-berlin.de (Stefan Ram):

> Wouldn't the straightforward
>
> struct fun
> { bool operator()
> ( const ::std::set< int >& x, const ::std::set< int >& y) const
> { return x.size() == y.size() ? x < y : x.size() < y.size(); }};
>
> using setset = ::std::set < ::std::set< int >, fun >;
>
> work?

Indeed, and that's what I am doing now, see my answer to Öö. But whether
this is straightforward (compared to my initial idea which seemed much
more straightforward to me) lies in the eye of the beholder. ;-)


Juha Nieminen

unread,
Dec 12, 2016, 8:32:20 AM12/12/16
to
Ralf Goertz <m...@myprovider.invalid> wrote:
> typedef std::set< std::set<int>,
> [](const std::set<int>&x,const std::set<int>&y)

[](){} is not a type, it's an object. You can't use it as a type.

Alf P. Steinbach

unread,
Dec 12, 2016, 10:19:15 AM12/12/16
to
On 06.12.2016 14:03, Ralf Goertz wrote:
>
> is it possible to have a lambda expression as a template argument?

A lambda that doesn't capture converts willingly to pointer to function,
which could have been a template argument except for

* there is no such conversion for template arguments, and

* the standard enumerates what kinds of values can be template
arguments, as quoted by Stefan Ram else-thread, and lambdas are not in
that list.


> If not why not?

See above.


> I get an error when I try to compile the following
>
> typedef std::set< std::set<int>,
> [](const std::set<int>&x,const std::set<int>&y){
> return x.size()==y.size() ? x<y : x.size()<y.size();
> }> Setset;
>
> error: lambda-expression in template-argument
>
> Background is that I'd rather have sets with fewer elements sorted
> before sets with more elements.

[code]
#include <set>

auto main()
-> int
{
using namespace std;
using Int_set = set<int>;
using Comparator_func = auto(*)(Int_set const&, Int_set const&) ->
bool;
using Set_of_sets = set<Int_set, Comparator_func>;
Set_of_sets blah{ [](Int_set const&x, Int_set const& y )
{
return x.size()==y.size() ? x<y : x.size()<y.size();
} };
}
[/code]


Cheers & hth.,

- Alf


0 new messages