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
dyn Fn(x) -> y
in Rust? –
Housefather std::function<…>
instances so the signatures are compatible, but with runtime overhead. –
Devinne 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).
summer
will have access to each other's private sum
variable, as access keywords in C++ are per-class, not per-instance. Because of this I'd argue it is not a closure (as encapsulation is a property many people expect). Lambdas on the other hand do not break this encapsulation, as each has a unique type. –
Rogelioroger private: int sum
means the member can be accessed only by member functions, but it still belongs to the instance, not to the class. static int sum
would belong to the class. –
Strategist class X { int x; public: X(int x): x(x) { } int getX(const X& instance) const { return instance.x; } void setX(X& instance, const int newX) { instance.x = newX; } }; int main() { X a(0); X b(1); // Read access std::cout << a.getX(b) << std::endl; // Write access a.setX(b, 2); std::cout << b.getX(b) << std::endl; }
–
Rogelioroger public
, private
, and protected
are compile-time guarantees and are on a per-class basis, not per-instance. –
Rogelioroger 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
}
my_f()
again after my_f1()
, because it might still be the same variable that you have just directly assigned with the call to make_my_closure
. –
Ultrafilter x
is a temporary value in make_my_closure
. So IMO it would not make sense. I added the case you asked. Which behave as expected –
Hydromechanics 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;
}
© 2022 - 2024 — McMap. All rights reserved.