Estaba leyendo sobre cierres en la red. Me preguntaba si C++ tiene una instalación in-build para cierres o hay alguna manera de implementar cierres en C++.¿Tenemos cierres en C++?
Respuesta
El último estándar de C++, C++11, tiene cierres.
http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions
http://www.cprogramming.com/c++11/c++11-lambda-closures.html
Sí, C++ 11 tiene cierres nombrados lambdas.
En C++ 03 no hay soporte incorporado para lambdas, pero existe la implementación Boost.Lambda.
Sospecho que depende de lo que quiere decir con el cierre. El significado que he usado siempre implica la recolección de basura de algún tipo (aunque creo que podría implementarse utilizando el recuento de referencias); a diferencia de lambdas en otros lenguajes , que capturan referencias y mantienen el objeto referenciado con vida, C++ lambdas captura un valor, o el objeto al que se refiere es no mantenido vivo (y la referencia puede colgarse fácilmente).
Si usted entiende el cierre como una referencia a una función que tiene un contexto integrado, persistente, oculto y unseparable (memoria, estado), que sí:
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 cloure
int x = 4;
int y = my_add_3_closure(x);
std::cout << y << std::endl;
la próxima uno modifica su estado:
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;
No se puede hacer referencia (acceso) al estado interno desde afuera.
Dependiendo de cómo lo defina, un cierre puede contener una referencia a más de una función o dos cierres pueden compartir el mismo contexto, es decir, dos funciones pueden compartir el mismo estado persistente, ...,.
El cierre significa que no contiene variables libres: es comparable a una clase con solo atributos privados y solo método (s) público (s).
El comportamiento es similar a un cierre pero no diría que es un cierre. – Setepenre
@Stepenre ¿cuál sería la diferencia? – Zrin
Esto apenas parece un cierre, lo que tienes aquí es solo un objeto que contiene un estado modificado por un método, más algo de azúcar sintáctico debido a que es "operador()" en lugar de cualquier otro método. Haz que devuelva una lambda que dependa del estado, o de un parámetro del método, y luego estamos hablando. – dividebyzero
Sí, muestra cómo podría implementar una función con un estado sin utilizar un funtor.
#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
}
me olvidó la palabra clave mutable que introdujo un comportamiento indefinido (versión ruido metálico regresaba un valor de basura). Tal como está implementado, el cierre funciona bien (en GCC y clang)
Para estar realmente seguro, sería bueno ver qué pasa si ejecuta 'my_f()' de nuevo después de 'my_f1()', porque aún puede ser la misma variable que acaba de asignar directamente con la llamada a 'make_my_closure '. – dividebyzero
'x' es un valor temporal en' make_my_closure'. Así que IMO no tendría sentido. Agregué el caso que me pidió. Que se comportan como se esperaba – Setepenre
- 1. ¿Por qué tenemos cierres en JavaScript?
- 2. Cierres y Lambda en C#
- 3. Cierres en Scala vs Cierres en Java
- 4. Cómo emular a los cierres en c
- 5. Rubí bloques/cierres de Java en C
- 6. Javascript Cierres
- 7. ¿Tenemos transacciones en MS-Access?
- 8. ¿Tenemos un autochomp en Perl?
- 9. Son cierres en javascript recompiladas
- 10. Cuando tenemos que usar DBNull.Value, null y "" en C# .Net?
- 11. ¿Por qué no tenemos <cstdfloat> en C++?
- 12. Cierres en Java 7
- 13. Cierres (en Haskell)
- 14. Cierres en Ruby
- 15. Cierres en Python
- 16. cierres Scala en Wikipedia
- 17. Invocación Groovy cierres
- 18. Tratando con la falta de cierres en Objective-C
- 19. ¿Cierres en los delegados del controlador de eventos C#?
- 20. ¿Hay aa manera de lograr cierres en C
- 21. Cierres y cuantificación universal
- 22. Aplicación parcial y cierres
- 23. Cierres en un bucle for
- 24. Serialización de cierres en groovy
- 25. ¿Por qué tenemos objetos invocables en python?
- 26. ¿Cierres y alcance dinámico?
- 27. Groovy: Cierres o Métodos
- 28. cierres léxicos sobre macrolet?
- 29. malentendido de JavaScript cierres
- 30. cierres y objetos
Además de la respuesta siguiente, también consulte http://en.cppreference.com/w/cpp/language/lambda para obtener más información sobre una página de referencia. –
Aparentemente mucha gente todavía mezcla funciones anónimas con cierres. Todavía no está claro para mí si C++ 11 admite cierres, o simplemente funciones anónimas ("lambdas"). No esperaría que C++ admitiera cierres reales en el mismo sentido que en JavaScript, Python, Scala y otros, lo encontraría muy sorprendente. – dividebyzero
Demostrando que estoy equivocado, sí, capta las variables en contexto, por copia e incluso por referencia, aparentemente, la única peculiaridad es que no hay recolección de basura ... Todavía me gustaría entender mejor cómo funciona todo esto en la práctica http: // en.cppreference.com/w/cpp/language/lambda – dividebyzero