Lambda function variables in C++11 - c++

There are two ways to use lambda function variable:
std::function<int(int, int)> x1 = [=](int a, int b) -> int{return a + b;};
//usage
void set(std::function<int(int, int)> x);
std::function<int(int, int)> get();
And:
std::function<int(int, int)>* x2 = new std::function<int(int, int)>([=](int a, int b) -> int{return a + b;});
//usage
void set(std::function<int(int, int)>* x);
std::function<int(int, int)>* get();
I would like to know what are the differences, because I do not know how the lambda function data is stored.
I would like to know the best way in terms of peformance, memory usage and the best way to pass a lambda function as argument or return lambda function.
I would prefer to use pointers if the size of the lambda function object is bigger than 4 or to avoid errors (if some kind of copy constructor is executed when I do an attribution or if some kind of destructor is executed when I do not want).
How should I declare lambda function variables?
EDIT
I want to avoid copies and moves, I want to continue to use the same function again.
How should I change this example?
int call1(std::function<int(int, int)> f){
return f(1, 2);
}
int call2(std::function<int(int, int)> f){
return f(4, 3);
}
std::function<int(int, int)>& recv(int s){
return [=](int a, int b) -> int{return a*b + s;};
}
int main(){
std::function<int(int, int)> f1, f2;
f1 = [=](int a, int b) -> int{return a + b;};
f2 = recv(10);
call1(f1);
call2(f1);
call1(f2);
call2(f2);
}
I cannot return reference in the function recv:
warning: returning reference to temporary
Is this a good solution?
int call1(std::function<int(int, int)>* f){
return (*f)(1, 2);
}
int call2(std::function<int(int, int)>* f){
return (*f)(4, 3);
}
std::function<int(int, int)>* recv(int s){
return new std::function<int(int, int)>([=](int a, int b) -> int{return a*b + s;});
}
int main(){
std::function<int(int, int)> f1 = [=](int a, int b) -> int{return a + b;};
std::function<int(int, int)> *f2 = recv(10);
call1(&f1);
call2(&f1);
call1(f2);
call2(f2);
delete f2;
}
EDIT (Conclusion)
A lambda function object is like any object that is instance of a class. The rules for allocation, arguments and attribution are the same.

It doesn't make sense to create pointer of std::function. It just doesn't benefit you in any way. Instead of benefits, it puts more burden on you, as you've to delete the memory.
So the first version (i.e the non-pointer version) is all that you should go for.
In general, like a rule of thumb, avoid new as much as possible.
Also, you don't need std::function everytime you use lambda. Many times, you could just use auto as:
auto add = [](int a, int b) { return a + b;};
std::cout << add(100,100) << std::endl;
std::cout << add(120,140) << std::endl;

You've made it clear that you want to use pointers. So... do that.
But at least use a smart pointer. Proper use of std::shared_ptr would prevent a number of problems. Of course, you have to make sure to avoid circular references, but for lambdas, that seems unlikely.
Granted, it's still a terrible idea. But it's only terrible in the sense of being a completely pointless premature optimization done to make yourself feel better about passing things around, rather than having any actual measurable benefit in your code's actual running time. At least with a shared_ptr, you're less likely to accidentally delete the memory or run into exception safety issues.
I'm going to ignore the bad C++ practice of heap-allocating something you could just as easily stack allocate, as well as the pain of tracking this memory without the use of a smart pointer. This will assume that you know what you're doing and will instead focus on the "performance" and "memory usage" issues you asked about.
Do not take this as an endorsement of what you're wanting to do.
std::function will generally be implemented by doing an internal heap allocation of some object; that's necessary due to the type-erasure. So it will be at least one pointer in size; possibly more. The size of the heap allocation will likely be a vtable pointer + the size of your lambda class. And the size of that is governed by how much stuff you capture and whether it is by value or reference.
Like most C++ standard library objects, std::function is copyable. Performing a copy will actually copy it, not do a pretend copy where you now have two objects with the same pointer. So each one will have an independent copy of the internal heap object. That is, copying it will mean doing another heap allocation. This will also copy the lambda itself, which means copying everything that's captured within it.
However, like most C++ standard library objects, std::function is movable. This does not do any memory allocation whatsoever.
Therefore, if you want to do this, it's pretty cheap:
std::function<int(int, int)> x1 = [=](int a, int b) -> int{return a + b;};
//usage
void set(std::function<int(int, int)> x);
const std::function<int(int, int)> &get();
set(std::move(x1)); //x1 is now *empty*; you can't use it anymore.
Your set function can move it into its own internal storage as needed. Note that get now returns a const&; this is contingent on the storage for these functions not going anywhere.
How cheap will move be? It will probably be the equivalent of copying just the fields of std::function, as well as blanking or otherwise neutralizing the original one. Unless you're in performance-critical code, this will not be anything you should ever be concerned about.

Here are the guidelines I tend to follow with the "functional C++" these new lambda expressions (plus std::function & std::bind) give you. Feel free to ignore them or adopt them as you see fit:
1) Assign any lambda you want to have a name as a std::function. If you're passing it into some function "X(..)" and never looking at it again, declare it in the function call so that "X" can take advantage of the fact that it is a temporary.
// I want a real name for this (plan to use multiple times, etc.)
// Rarely are you going to do this without moving the lambda around, so
// declaring it as 'auto' is pointless because C++ APIs expect a real type.
std::function<double(double)> computeAbs = [](double d) -> double { return fabs(d); };
// Here, we only ever use the lambda for the call to "X".
// So, just declare it inline. That will enforce our intended usage and probably
// produce more efficient code too.
X([](double r) -> double { return fabs(r); });
2) If you plan to move functions all over the place, use some sort of reference-counted wrapper around std::function. The idea is to pass around a safe pointer to the actual std::function, thus avoiding costly copies as well as worrying about new and delete.
Building your own class for doing this can be a pain, but it will ensure you only take the hit for actually converting your lambda, function ptr, etc. into a std::function once.
You can then provide an API like "GetFunction" to return the std::function you carry by value for APIs that expect them.
3) For public APIs taking std::function or lambdas, just pass by value.
Yes, you CAN get passing by reference or even r-value (those '&&') references to work and they're even the right solution in some situations. But lambdas are nasty in that their actual type is literally unknowable to you. However, they are all convertible to std::function in the same way that all primitive types can convert to 'int', so passing them into functions involves using the same tricks that let you pass chars and floats into a function like "f(int a)".
Namely, you create functions "f" that are either templated on the TYPE of the functor argument like:
template<typename Functor>
double f(Functor absFunc);
OR, you make everybody normalize to std::function:
double f(std::function<double(double)> absFunc);
Now, when you call "f([](double r) -> double { return fabs(r); })" the compiler knows to how to handle it. Users get something that 'just works' without having to code around your API, which is what you want.

Related

What is the benefit of && on a lambda-expression?

I'm seeing code that looks like this:
template<class Function>
void MyFunc(Function&& function) { function(...); }
What's the advantage of && here, as opposed to just copying the function by value? For reference, I'm using C++14.
The problem comes from avoiding copies.
Imagine this:
auto lambda = [ptr = std::make_unique<int>(0)]() mutable {
std::cout << *ptr;
ptr = std::make_unique<int>(*ptr + 1); // why not?
};
MyFunc(lambda); // use it normally
MyFunc([]{ std::cout << " end"; }); // use by using a temporary lambda
lambda() // just call the function after that
If the signature is MyFunc(Function f), it would require a std::move and the lambda would not be useable after the call.
If the signature is MyFunc(Function const& f), it would not work since the lambda is mutable.
If it was MyFunc(Function& f) then the temporary would not work.
You're basically left with MyFunc(Function&& f).
The real question however is "Do I need to support all these cases?"
I would tell: most of the time no. Most of the time, receiving the lambda by value is the simplest and support almost every cases. This is the way the STL went.
Why? Because perfect forwarding of function objects is really hard to get perfect, and you cannot call the function multiple times in most of the cases in a pefectly generic way. I would perfect forward a function only if I want to wrap it, want to completely avoid copies and I expect function objects that are ref qualified to temporaries.

Why should I not use `const` in this simple function?

When learning C++, one of the first functions one gets for learning the concept of a function is something like
int add(int a, int b)
{
return a+b;
}
Now I was wondering: Should I use the const-keyword here, or rather not, resulting in
int add(const int a, const int b)
{
return a+b;
}
But would that make sense? Would it speed my program up, do some other important stuff, or just increase confusion?
From the caller's perspective, both the first and the second form are the same.
Since the integers are passed by value, even if the function modifies a and b, the modified values are copies of the original and won't be visible to the caller.
However, from the function implementer's perspective there's a difference. In fact, in the second form:
int add(const int a, const int b)
you will get a compiler error if you try to modify the values of a and b inside the function's body, as they are marked as const.
Instead, you can change those values if you omit the const.
Again, those modifications will not be visible to the caller.
If you are actually struggling with correctness bugs in your codebase where const would have helped, then add const.
That said, there are related issues that you should consider. Top-level qualifiers of function parameters aren't part of the function type, so your function type is still just int(int, int). (The qualifiers only affect the parameter variables in the function definition.) That means that any declaration of the function also ignores qualifiers, so int add(int, int) and int add(const int, int) and int add(int, const int) all declare the same function. So you have to decide on a policy for how you write header files. And now you have three essential positions you can take:
Always qualify in both declaration and definition. The upside is that this perhaps keeps code looking "consistent" (think copy/pasting when creating implementations). The downside is that the qualifiers have nothing to do with the interface, and are not at all enforcible (you can change the definition later!), so at best it's noise, at worst it's wrong.
Qualify in the definition, but not in the other declarations. The upside is that this communicates the interface correctly and you still get const checking in the definition. The downside is that some people might be confused by the discrepancies in spelling. (Just like people may be confused that a static constexpr T foo; class member can be defined with const T C::foo;.)
Don't qualify either. The upside is that it's consistent, clean, easy to remember and minimal. The downside is that you're missing out on correctness checks in your definition.
There's no right answer. If you're the codebase owner or project lead, you should decide based on what the biggest problems in your codebase and team are. (My personal position is to stick with (3) until you have a good reason to change.)
Using int add(const int a, const int b) means that you cannot modify the input parameters within the function body.
Perhaps the compiler can make some optimisations based on that, so it ought therefore to be never slower than the non-const equivalent. But I have never observed this effect in practice.
Passing const parameters can also increase the stability of your code base, particularly in a collaborative project.
All this said though, I find it too verbose, rather unnecessary, and would use int add(int a, int b). Very occasionally, for particularly long functions, I exploit the fact that you can declare the function with non-const parameters, and define it with the parameters const.
I feel like everyone is dancing around this part of the answer...
It's true that using const will keep the function from modifying the value of your int a & b while inside the function. This can be extremely useful, so use it as you wish, of the compiler allows it. But, the function caller will never know about any changes to a & b once the function finishes. So even if a & b are changed, no one except the defined function will know their updated values.
int funcB(int a, int b)
{
a = a+1;
b = b*b;
return a+b;
}
void funcA()
{
int s = 5;
int t = 6;
int result = funcB(s, t);
printf("%f + %f = %f", s,t, result);
}
funcA prints: "5 + 6 = 42"
Const protection is often used when passing values by reference, ie:
int function(const int &a, const int &b) {}
This passes a reference of a and b to the function (ie, does not make copies of a and b but passes only a memory address of that variable, aka: the handle). When passing a variable by reference, any changes made to the variable are remembered outside the scope of the function and can change the way your program runs. This is generally undesired behavior.
So if you rework funcB from above and pass by reference:
int funcB(int &a, int &b)
{
a = a+1;
b = b*b;
return a+b;
}
funcA prints: "6 + 36 = 42"
If you add const correctness to funcB:
int funcB(const int &a, const int &b)
{
a = a+1;
b = b*b;
return a+b;
}
I don't think the compiler will let you even do this since you would be explicitly trying to modify values that you've protected via const.
Another time when it may be really important to use const is when you're passing by pointer, instead of reference or copy...
int funcB(int *a, int *b)
{
a = a+1;
b = b*b;
return a+b;
}
Unless you're a pointer expert, avoid passing pointers without const pretention. This func will likely attempt to iterate the index of your pointer arrays and you'd open yourself up to run time errors related to out of bound memory. You could accidently see memory from an entirely different program... but probably not.
Lastly, since you're just passing int, there's no practical need to pass by reference (which is done often to keep from adding complex data into memory because each non-reference or non-pointer pass to functions copies the value into memory for the life of the function being called) since the memory footprint of int is so small. Unless, you're working with specialized hardware that has extremely limited memory, then it may be useful; this won't apply to most standard computers and desktops made within the past 20 years, or smart phones.
int add(const int a, const int b)
{
return a+b;
}
Here const in used so that the function does not modify the original values of a and b by any chance.
In the above example it does not make sense. But if it would have been an example like
int add(const int *a, const int *b)
{
//*a = 10; //This will throw error.
return a+b;
}
In functions where objects,arrays or such data types are passed its a good approach to use const to avoid mutation of original data structure.
If you want to be truly const correct, then you should add it, but in reality all it will do is make you type and read more.
Nothing will go faster, and while it could mean that your variables go into another location in memory, it's unlikely to on most modern machines.
What it will stop you doing is accidentally assigning them values, but as they're local to the function, it's relatively unimportant. What would matter is if they were references, as this demonstrates your intent to the caller to not change them.
You can use const there if you like.
It is unlikely to speed up your program because any reasonable compiler can already see that no code path alters the value of a or b and make any optimisations it needs.
a and b are int, which are passed by value so making them const has no impact on the users of this function.
The only possible advantage is where your function is long and more complex and you want to avoid possible programming errors where the original values of a or b are changed during the function.
If you will use const then you cannot modify the value of a,b. Thats why we don't use const.
The primary purpose of constness is to provide documentation and prevent programming mistakes. Const allows you to make it clear to yourself and others that something should not be changed. Moreover, it has the added benefit that anything that you declare const will in fact remain const short of the use of forceful methods. It's particularly useful to declare reference parameters to functions as const references:
bool SomeFunction (const myObj& obj);
Here, a myObj object is passed by reference into SomeFunction. For safety's sake, const is used to ensure that SomeFunction cannot change the object--after all, it's just supposed to make sure that the object is in a valid state. This can prevent silly programming mistakes that might otherwise result in damaging the object (for instance, by setting a field of the class for testing purposes, which might result in the field's never being reset). Moreover, by declaring the argument const, users of the function can be sure that their object will not be changed and not need to worry about the possible side effects of making the function call.
moreover, The reason is that const for the parameter only applies locally within the function, since it is working on a copy of the data. This means the function signature is really the same anyways. It's probably bad style to do this a lot though. I personally tend to not use const except for reference and pointer parameters.
as a law of thumb we are advised to use const as much as possible because we get a great help from the compiler so whenever we try to change a constant the mistake will be caught by the compiler; it's a good thing avoiding being caught in error-prones.
the second thing: a and b passed by value so they are created as local constants But as long as they are not changeable why we need copies??
the good thing is to pass a const reference which means never change parameters and avoid copies (by value):
int add(const int& a, const int& b) // now there are no copies of a and b in addition we cannot modify a and be
{
return a+b;
}

Smart pointer to lambda

I'm trying to make a function that accepts a shared pointer to some functor. With manually crafted functors there're no problems, but with lambda there are. I know that I can't use decltype with lambda - every new lambda declaration creates a new type. Right now I'm writing:
auto lambda = [](int a, float b)->int
{
return 42;
};
using LambdaType = decltype(lambda);
shared_ptr<LambdaType> ptr{ new LambdaType{ lambda } };
It works, but looks ugly. Moreover there's a copy constructor call! Is there any way to simplify?
You could use std::function as type.
Lambdas are merely auto written invokable objects to make simple code simple. It you want something beyond their default automatic storage behavior, write the type they write yourself.
It is illegal to have a lambda type in an unevaluated context. In an evaluated context, it creates a lambda in automatic storage. You want it on the free store. This requires at least logically a copy.
A horrible hack involving violating the unevaluated context rule, sizeof/alignof, aligned_storage_t, placement new, possibly unbounded compile time recursion (or maybe one with a static_assert), returning pointers to local variables, and the aliasing constructor of shared ptr, and requiring callers to write insane code might avoid calling the copy/move. But it is a bad idea, and simply using invokable objects is easier.
Of course, accepting the copy/move makes it trivial. But at that point, just use std::function unless you need something like varargs.
You state you do not want to force users to use std::function; but std::function would implicitly convert a compatible lambda into itself.
If you are willing to accept a copy, we can do this:
template<class T>
std::shared_ptr<std::decay_t<T>>
auto_shared( T&& t ) {
return std::make_shared<std::decay_t<T>>(std::forward<T>(t));
}
then auto ptr = auto_shared( [x=0]()mutable{ return x++; } ); is a non-type-erased shared pointer to a counting lambda. The lambda is copied (well, moved) into the shared storage.
If you want to avoid that copy, the client can write a manual function object and call make_shared<X>(ctor_args) on it.
There is no reasonable way to separate a lambdas type from its construction in C++ at this point.
if you catch something in lambda, it becomes algorithmically same as std::function, so use it freely. Also, std::function implements captured values memory management, so using std::shared_ptr on top of it is not required.
If you catch nothing, lambda is convertible to simple function pointer:
int(*ptr)(int,int) = [](int a, int b) -> int {
return a+b;
};
Functions are allocated statically and definitely shouldn't be deleted. So, you don't actually need std::shared_ptr

test std::function validity after bind to member function

For the struct:
struct A {
int var = 10;
void check() {
std::cout << "var is " << var << std::endl;
}
};
Say I create a std::function object of A::check(), using a dynamically allocated a object:
auto a_ptr = std::make_unique<A>();
std::function<void()> f = std::bind(&A::check, a_ptr.get());
//...later/elsewhere...
f();
It would be nice for safety if I could test f to see if the bound A object is still alive. Is it possible to retrieve that information from f directly? Assume a_ptr is not accessible from the call point, so I can't test against a_ptr directly. Using std::function's operator bool, or testing f against nullptr don't work.
So you basically want your function object to test for the existence of the A instance managed by a_ptr, i see 3 ways of doing this with the current c++ std features.
-- Lambda with a reference to the unique_ptr
auto a_ptr = std::make_unique<A>();
std::function<void()> f = [&] { if (a_ptr) a_ptr->check(); };
//...later/elsewhere...
f();
This requires that the pointer is still alive anytime the function object is alive.
-- Lambda with a copy of the shared_ptr
auto a_ptr = std::make_shared<A>();
std::function<void()> f = [=] { if (a_ptr) a_ptr->check(); };
//...later/elsewhere...
f();
Same thing but without requirements on the lifetime relationship at the expense of some additional performance cost which is mainly the copy of a shared pointer, probably totally worth the headache it saves in most cases (i'm going to be burned by the optimisation guys for this one).
-- Custom deleter in your smart pointer that resets your function
std::function<void()> f;
auto a_ptr = std::unique_ptr<A, std::function<void(A*)>>(new A, [&](A*){ f = nullptr;});
f = std::bind(&A::check, a_ptr.get());
//...later/elsewhere...
a_ptr.reset();
if (f)
f();
This requires that somehow your deleter can access the function to reset it, whether it is directly or through a storage system in your classes (containers of functions are a nice design imo).
You can also create more elaborated systems with your own primitives but that would lead you further away from the standard library. Ultimately you'll have to choose what's best in your situation mainly based on the lifespan and ownership relationships of your objects.
Well, this one is easy, use std::shared_ptr.
when you think about it , you basically want to ensure that some entity in you program is valid as long as something is using it.
In other words, you are looking for a shared_ptr.
Otherwise, the design looks a bit weird, if some single entity in your program is owning a_ptr, it should be the single owner of all the std::functions which uses this resource, which is not your intention. if that owner is not the owner of the std::function you are highly increasing the probability of segmentation faults, heap corruption and other stuff you don't want.

Is there any way to go back from `std::function` to a pointer?

Imagine the following scenario:
typedef std::function<float(float)> A;
typedef float(*B)(float);
A foo();
void bar(B b);
You wish to do something along the lines of:
bar(foo());
Obviously this does not work. Mainly because A can contain a state and B is a function pointer. What if we know that A does not contain a state and we wish to somehow take it's "meaning" and put it into something that can be passed for a B?
Is it impossible?
If you can ensure that the callable object stored in A is a function pointer or a lambda with an empty capture list, you can simply get a function pointer in this way:
foo().target<B>();
In general, a std::function can "box" some closure (e.g. the value of some lambda function). And a closure contains both code and data (the closed values). So I believe that you cannot portably convert it to a naked function pointer. BTW, because conceptually closures are mixing code and data languages not providing them (like C) practically requires callbacks (i.e. the convention to pass every function pointer with some additional data, look into GTK for a concrete example).
Some implementation specific tricks might make a trampoline function on the stack (e.g. dynamically generate, perhaps with asmjit, some machine code containing a pointer to the closure, etc.). But this is not portable and system specific (in particular because the stack needs to be executable)
What if we know that A does not contain a state and we wish to somehow take it's "meaning" and put it into something that can be passed for a B?
Even that isn't sufficient. std::function provides a target() member function, that if you know the exact type of the underlying functor, you can get it back. So we can do, for instance:
void print(int i) { std::cout << i; }
std::function<void(int)> f = print;
auto ptr = f.target<void(*)(int)>(); // not null
(*ptr)(42); // works
However, even if our functor f doesn't contain state, that doesn't mean that its underlying type is precisely void(*)(int). It could be a completely different function pointer, in which case we wouldn't be able to pull it out:
int square(int i) { return i*i; }
f = square;
ptr = f.target<void(*)(int)>(); // nullptr!
Or it could be a lambda, in which case we wouldn't even be able to name the type, much less pull it out:
f = [](int i){ std::cout << i; }; // same as print, right?
ptr = f.target<void(*)(int)>(); // ... nope :'(
Basically, type erasure is really type erasure. If you need the original underlying type, that's likely indicative of a bad design.