Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can the 'type' of a lambda expression be expressed?

Thinking of lambda expressions as 'syntactic sugar' for callable objects, can the unnamed underlying type be expressed?

An example:

struct gt {     bool operator() (int l, int r) {         return l > r;     } } ; 

Now, [](int l, int r) { return l > r; } is an elegant replacement for the above code (plus the necessary creation of callable objects of gt), but is there a way to express gt (the type) itself?

A simple usage:

std::set<int, gt> s1;  // A reversed-order std::set // Is there a way to do the same using a lambda? std::set<int, some-magic-here-maybe([](int l, int r) { return l > r; }) > s2; 
like image 711
Yehoshafat Hashiloni Avatar asked Oct 05 '10 20:10

Yehoshafat Hashiloni


People also ask

What is the type of lambda expression?

The lambda expressions have a very simple, precise syntax and provide flexibility to specify the datatypes for the function parameters. Its return type is a parameter -> expression body to understand the syntax, we can divide it into three parts.

Can lambda expression have return type?

A return statement is not an expression in a lambda expression. We must enclose statements in braces ({}). However, we do not have to enclose a void method invocation in braces. The return type of a method in which lambda expression used in a return statement must be a functional interface.

How many types of lambda expressions are there?

Types of Lambda Body In Java, the lambda body is of two types. () -> System. out. println("Lambdas are great");

What is the type of a lambda expression C++?

[C++11: 5.1. 2/3]: The type of the lambda-expression (which is also the type of the closure object) is a unique, unnamed non-union class type — called the closure type — whose properties are described below.


1 Answers

No, you cannot put it into decltype because

A lambda-expression shall not appear in an unevaluated operand

You can do the following though

auto n = [](int l, int r) { return l > r; }; std::set<int, decltype(n)> s(n); 

But that is really ugly. Note that each lambda expression creates a new unique type. If afterwards you do the following somewhere else, t has a different type than s

auto n = [](int l, int r) { return l > r; }; std::set<int, decltype(n)> t(n); 

You can use std::function here, but note that this will incur a tiny bit of runtime cost because it needs an indirect call to the lambda function object call operator. It's probably negligible here, but may be significant if you want to pass function objects this way to std::sort for example.

std::set<int, function<bool(int, int)>> s([](int l, int r) { return l > r; }); 

As always, first code then profile :)

like image 197
Johannes Schaub - litb Avatar answered Sep 21 '22 06:09

Johannes Schaub - litb