Do we have closures in C++? - c++

I was reading about closures on the net. I was wondering if C++ has a built-in facility for closures or if there is any way we can implement closures in C++?

The latest C++ standard, C++11, has closures.
http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions
http://www.cprogramming.com/c++11/c++11-lambda-closures.html

If you understand closure as a reference to a function that has an embedded, persistent, hidden and unseparable context (memory, state), then yes:
class add_offset {
private:
int offset;
public:
add_offset(int _offset) : offset(_offset) {}
int operator () (int x) { return x + offset; }
}
// make a closure
add_offset my_add_3_closure(3);
// use closure
int x = 4;
int y = my_add_3_closure(x);
std::cout << y << std::endl;
The next one modifies its state:
class summer
{
private:
int sum;
public:
summer() : sum(0) {}
int operator () (int x) { return sum += x; }
}
// make a closure
summer adder;
// use closure
adder(3);
adder(4);
std::cout << adder(0) << std::endl;
The inner state can not be referenced (accessed) from outside.
Depending on how you define it, a closure can contain a reference to more than one function or, two closures can share the same context, i.e. two functions can share the same persistent state.
Closure means not containing free variables - it is comparable to a class with only private attributes and only public method(s).

Yes, This shows how you could implement a function with a state without using a functor.
#include <iostream>
#include <functional>
std::function<int()> make_my_closure(int x) {
return [x]() mutable {
++x;
return x;
};
}
int main() {
auto my_f = make_my_closure(10);
std::cout << my_f() << std::endl; // 11
std::cout << my_f() << std::endl; // 12
std::cout << my_f() << std::endl; // 13
auto my_f1 = make_my_closure(1);
std::cout << my_f1() << std::endl; // 2
std::cout << my_f1() << std::endl; // 3
std::cout << my_f1() << std::endl; // 4
std::cout << my_f() << std::endl; // 14
}

I suspect that it depends on what you mean by closure. The meaning I've
always used implies garbage collection of some sort (although I think it
could be implemented using reference counting); unlike lambdas in other
languages, which capture references and keep the referenced object
alive, C++ lambdas either capture a value, or the object refered to is
not kept alive (and the reference can easily dangle).

Yes, C++11 has closures named lambdas.
In C++03 there is no built-in support for lambdas, but there is Boost.Lambda implementation.

Strictly speaking. 'Closure' is LISP only. Use Let returns lambda as last commands. 'Let Over Lambda'. This is possible only for LISP because of infinite scope with lexical scoping. I don't know any other language support this natively until know.
(defun my-closure ()
(let ((cnt 0))
(lambda ()
(format t "called : ~A times" (incf cnt)))))

You can achive similar functionality using static variables and lambdas.
#include <iostream>
#include<functional>
int main()
{
std::function<std::function<int()>()> generator_function=[]()->std::function<int()>{
static int i=0;
return [&]()->int{
return i++;
};
};
std::function<int()> iterator_function=generator_function();
std::cout<<iterator_function()<<std::endl; //1
std::cout<<iterator_function()<<std::endl; //2
std::cout<<iterator_function()<<std::endl; //3
std::cout<<iterator_function()<<std::endl; //4
return 0;
}

Related

How can I make a constructor create a different lambda each time when called?

I have this simple code:
#include <iostream>
#include <functional>
class a {
public:
a() {
func = [] {
static int i = 0;
i++;
std::cout << i << std::endl;
};
}
std::function<void()> func;
};
int main()
{
a a1;
a1.func();
a a2;
a2.func();
}
I expected an output like this:
1
1
But instead it was:
1
2
Then I checked the memory addresses of the lambdas in the two instances of a and they were the same. This means that the lambda is created once and then used in all instances. What I am looking for is to make the constructor create a different lambda every time when it gets called. I turned off the compiler optimizations but there was no effect.
INFO: I am using MSVC.
Conceptually, you do have separate instances of the lambda. What you have witnessed might be a compiler optimization, but the actual issue is that static makes i owned by the function body itself, and thus shared by all instances of your lambda.
What you want instead is to make i a member of each lambda instance, which you can do with an extended capture list:
func = [i = 0]() mutable {
i++;
std::cout << i << std::endl;
};
If you are on a C++11 only compiler, you can drop the lambda syntax sugar and return to the function objects (which lambdas are a shorthand version of defining)
struct CallCounter
{
int i = 0;
void operator()()
{
i++;
std::cout << i << std::endl;
}
};
class a {
public:
std::function<void()> func = CallCounter{};
};

C++ lambda capture list by value or by reference doesn't give me different results

I am having the below code :
std::vector<std::function<void()>> functors;
class Bar
{
public :
Bar(const int x, const int y):d_x(x),d_y(y){}
~Bar(){
cout << "Destructing Bar" << endl;
}
void addToQueue()
{
const auto job = [=](){
cout << "x:" << d_x << " y: " << d_y;
};
functors.push_back(job);
}
private :
int d_x,d_y;
};
void example()
{
cout << "Hello World" << endl;
{
shared_ptr<Bar> barPtr = make_shared<Bar>(5,10);
barPtr->addToQueue();
}
cout << "Out of scope. Sleeping" << endl;
usleep(1000);
functors[0]();
}
The output is as expected :
Hello World
Destructing Bar
Out of scope. Sleeping
x:5 y: 10
I am now capturing by value, which is why I assume when the Bar object gets destroyed, I can still access its member variables. If the above is right, I am expecting the below change to give me UB:
const auto job = [&](){
However, I still see the same result. Why is that? Have i understood something wrong?
EDIT Further on the above, what I want to understand from this example - is how can I have access to a class member variables in a lambda function even if object has been destroyed? I am trying to avoid UB and thought that passing by value is the way to go, but can't prove that the opposite isn't working.
This kind of confusion iss probably one of the reasons why C++20 deprecated the implicit capture of this with [=]. You can still capture [this], in which case you have the usual lifetime issues with an unmanaged pointer. You can capture [*this] (since C+=17), which will capture a copy of *this so you don't have lifetime issues.
You could also use std::enable_shared_from_this since you're using a std::shared_ptr in example, but that's a bit more complicated. Still, it would avoid both the copy and the UB when the lifetime issues.
In these examples you are capturing this and not any of the fields.
When capturing this, by design, it is never captured by copying the object or the fields.
The best way to capture a field by value is:
[field = field] () { }
Both versions of your code have undefined behaviour. barPtr is the only owner of the shared_ptr so your object is destructed at the end of the scope containing barPtr. Executing the lambda which has captured this from the object in barPtr has undefined behaviour.
The usual way to prevent this is for the lambda to capture a shared_pointer from shared_from_this to keep the object alive. E.g:
#include <vector>
#include <functional>
#include <iostream>
#include <memory>
std::vector<std::function<void()>> functors;
class Bar : public std::enable_shared_from_this<Bar>
{
public :
Bar(const int x, const int y):d_x(x),d_y(y){}
~Bar(){
std::cout << "Destructing Bar\n";
}
void addToQueue()
{
auto self = shared_from_this();
const auto job = [this, self](){
std::cout << "x:" << d_x << " y: " << d_y << "\n";
};
functors.push_back(job);
}
private :
int d_x,d_y;
};
int main()
{
std::cout << "Hello World\n";
{
std::shared_ptr<Bar> barPtr = std::make_shared<Bar>(5,10);
barPtr->addToQueue();
}
std::cout << "Out of scope\n";
functors[0]();
}
By capturing self the shared_ptr will now survive for at least as long as the lambda does.

How does a std::function object which return a std::function work when call by operator()?

Sample:
#include "stdafx.h"
#include <functional>
#include <iostream>
#include <string>
std::function<void(int)> Foo()
{
int v = 1;
int r = 2;
auto l = [v, r](int i)
{
std::cout << v << " " << r << " " << i << std::endl;
};
return l;
}
int main()
{
auto func = Foo();
func(3);
return 0;
}
Why func(3) can pass 3 to i which is the formal argument of the lambda in Foo(). I can't think out. thanks.
TL;DR: You don't pass your argument 3 into a function Foo. You pass it to a method of an object func.
A bit more detailed explanation is below.
First of all, I would like to clarify what a lambda is. A lambda in C++ is nothing more than an anonymous functor class, so essentially just a syntactic sugar. A closure is an instance of a lambda type. However, quite often you can hear words "lambda" and "closure" being used interchangeably.
So within your function Foo() you create a closure object l
auto l = [v, r](int i)
{
std::cout << v << " " << r << " " << i << std::endl;
};
which would be technically equivalent to this code:
struct Functor
{
Functor(int v, int r) : v_(v), r_(r) {}
void operator ()(int i) const {
std::cout << v_ << " " << r_ << " " << i << std::endl;
}
private:
int v_;
int r_;
};
Functor l(v, r);
Now, on the next line you return an std::function object.
return l; // actually creates std::function<void(int)>(l) and returns it
So in your main function a func is just an object which stores copies of values v, r obtained during a call to Foo() and defines operator(), similar to the struct above.
Therefore, calling func(3) you actually invoke an object method on a concrete object func, and without syntactic sugar it looks like func.operator()(3).
Here's a live example to illustrate my point.
Hope that helps to resolve your confusion.

C++11 lambda function - how to pass parameter

I used lambda function to pass it to std::condition_variable wait() function, but that is not the case. I use lambda functions that don't receive any parameters, and everything is absolutely clear for me. But I totally don't understand how is used lamdba function that have parameters list. Show lambda with parameters are used? How to pass parameters to them?
Show lambda with parameters are used? How to pass parameters to them?
It works exactly like with any other type of callable object:
#include <iostream>
int main()
{
auto l = [] (int i) { std::cout << "The answer is " << i; };
l(42);
}
Also notice, that you do not need to store a lambda in a variable in order to invoke it. The following is an alternative way to rewrite the above program:
#include <iostream>
int main()
{
[] (int i) { std::cout << "The answer is " << i; } (42);
// ^^^^
// Invoked immediately!
}
The type of a lambda function (the so-called "lambda closure") is defined by the compiler, and is a functor with a call operator whose signature is the one you specify when defining the lambda. Therefore, you call a lambda exactly as you would call a functor (i.e. exactly as you would call a function - or any callable object).
Thus, if you want to assign a lambda to an object, the best practice is to let the compiler deduce its type by using auto. If you do not want or cannot use auto, then you may:
Use function pointers for non-capturing lambdas (capturing lambdas are not convertible to function pointers). In the above case, thus, the following will also work:
#include <iostream>
int main()
{
void (*f)(int) = [] (int i) { std::cout << "The answer is " << i; };
f(42);
}
Use std::function (this is always possible, even if the lambda is capturing):
#include <iostream>
#include <functional>
int main()
{
std::function<void(int)> f = [] (int i)
{ std::cout << "The answer is " << i; };
f(42);
}
auto lambda = [] (int a, int b) { return a + b; };
assert(lambda(1, 2) == 3);
You don't even need a variable to hold your lambda -- you can call it directly:
std::cout << [](int n) { return n + 1 ; } (99) << std::endl ;

temporary object in range-based for

I know that in general the life time of a temporary in a range-based for loop is extended to the whole loop (I've read C++11: The range-based for statement: "range-init" lifetime?). Therefore doing stuff like this is generally OK:
for (auto &thingy : func_that_returns_eg_a_vector())
std::cout << thingy;
Now I'm stumbling about memory issues when I try to do something I thought to be similar with Qt's QList container:
#include <iostream>
#include <QList>
int main() {
for (auto i : QList<int>{} << 1 << 2 << 3)
std::cout << i << std::endl;
return 0;
}
The problem here is that valgrind shows invalid memory access somewhere inside the QList class. However, modifying the example so that the list is stored in variable provides a correct result:
#include <iostream>
#include <QList>
int main() {
auto things = QList<int>{} << 1 << 2 << 3;
for (auto i : things)
std::cout << i << std::endl;
return 0;
}
Now my question is: am I doing something dumb in the first case resulting in e.g. undefined behaviour (I don't have enough experience reading the C++ standard in order to answer this for myself)? Or is this an issue with how I use QList, or how QList is implemented?
Since you're using C++11, you could use initialization list instead. This will pass valgrind:
int main() {
for (auto i : QList<int>{1, 2, 3})
std::cout << i << std::endl;
return 0;
}
The problem is not totally related to range-based for or even C++11. The following code demonstrates the same problem:
QList<int>& things = QList<int>() << 1;
things.end();
or:
#include <iostream>
struct S {
int* x;
S() { x = NULL; }
~S() { delete x; }
S& foo(int y) {
x = new int(y);
return *this;
}
};
int main() {
S& things = S().foo(2);
std::cout << *things.x << std::endl;
return 0;
}
The invalid read is because the temporary object from the expression S() (or QList<int>{}) is destructed after the declaration (following C++03 and C++11 ยง12.2/5), because the compiler has no idea that the method foo() (or operator<<) will return that temporary object. So you are now refering to content of freed memory.
The compiler can't possibly know that the reference that is the result of three calls to operator << is bound to the temporary object QList<int>{}, so the life of the temporary is not extended. The compiler does not know (and can't be expected to know) anything about the return value of a function, except its type. If it's a reference, it doesn't know what it may bind to. I'm pretty sure that, in order for the life-extending rule to apply, the binding has to be direct.
This should work because the list is no longer a temporary:
#include <iostream>
#include <QList>
int main() {
auto things = QList<int>{};
for (auto i : things << 1 << 2 << 3)
std::cout << i << std::endl;
return 0;
}
And this should work because the binding is direct, so the rule can apply:
#include <iostream>
#include <QList>
int main() {
for (auto i : QList<int>{1, 2, 3})
std::cout << i << std::endl;
return 0;
}