Reputation: 215
I have plenty of C# experience before but I am new to C++. I have seen this problem when trying to use lambda as I used to do.
For example:
auto compare = [] (int i1, int i2) { return i1*2 > i2; }
Is there any way to define the lambda with a specific type, rather than auto deduction?
I am asking this because I want to define a common lambda for my class. This lambada will be used in multiple places so I don't want to define them multiple times. However, 'auto' can only be used on static members, while on the other hand, I want to access non-static fields in the lambda.
Upvotes: 15
Views: 10706
Reputation: 13002
The way to do this without the overhead of std::function
, if you feel a functor is too cumbersome, is to use function pointers, a typedef, and optionally a macro.
In your example, this function pointer would look like this:
bool (*compare)(int, int) = [] (int i1, int i2) { return i1*2 > i2; };
^^^^^^^^^^^^^^^^^^^^^^^^^
Note how compare
, the pointer's identifier, is tucked into the parenthesis, this trips people up sometimes, but it's the proper way to declare a function pointer.
You can write a typedef in the same way:
typedef bool (*Compare)(int, int);
The typedef name is where the identifier would ordinarily be. This allows you to now write the more concise:
Compare func = [] (int i1, int i2) { return i1*2 > i2; };
^^^^^^^^^^^^
If you allow yourself to use macros, you can go even further in terms of ergonomics:
#define CompareLambda [](int i1, int i2)
typedef bool (*Compare)(int, int);
...
Compare func = CompareLambda{ return i1*2 > i2;};
Macros and typedefs exist as tools to make your work as a programmer easier by helping you avoid repeating yourself, don't be afraid to use them.
Upvotes: 2
Reputation: 2193
You use std::function
, which can glob any lambda or function pointer.
std::function< bool(int, int) > myFunc = []( int x, int y ){ return x > y; };
See C++ Reference.
Upvotes: 19
Reputation: 7663
You can use as std::function<Signature>
as mentioned, but at the cost of type-erasing the lambda. This will add an indirection (basically a virtual function call) when you call your lambda. So keep in mind it is less efficient if you will use it in a context where this matters.
Upvotes: 0
Reputation: 45665
You could use std::function
, but if that's not going to be efficient enough, you could write a functor object which resembles what lambdas do behind the scenes:
auto compare = [] (int i1, int i2) { return i1*2 > i2; }
is almost the same as
struct Functor {
bool operator()(int i1, int i2) const { return i1*2 > i2; }
};
Functor compare;
If the functor should capture some variable in the context (e.g. the "this" pointer), you need to add members inside the functor and initialize them in the constructor:
auto foo = [this] (int i) { return this->bar(i); }
is almost the same as
struct Functor {
Object *that;
Functor(Object *that) : that(that) {}
void operator()(int i) const { return that->bar(i); }
};
Functor foo(this);
Upvotes: 5