Czytałem o zamknięciach w sieci. Zastanawiam się, czy C++ ma wbudowaną możliwość zamykania lub czy istnieje sposób, w jaki możemy zaimplementować zamknięcia w C++?Czy mamy zamknięcia w C++?
Odpowiedz
Najnowszy standard C++, C++11, ma zamknięcia.
http://en.wikipedia.org/wiki/C%2B%2B11#Lambda_functions_and_expressions
http://www.cprogramming.com/c++11/c++11-lambda-closures.html
Tak, C++ 11 ma zamknięcia nazwie lambdas.
W C++ 03 nie ma wbudowanej obsługi lambd, ale istnieje implementacja Boost.Lambda.
Podejrzewam, że to zależy od tego, co rozumiesz przez zamknięcie. Znaczenie, jakie mam zawsze używane, oznacza, że jakiś rodzaj zbierania śmieci (chociaż myślę, że można go zaimplementować za pomocą liczenia odwołań); w przeciwieństwie do lambdów w innych językach , które przechwytują referencje i utrzymują przy życiu obiekt odniesienia, którym jest obiekt odniesienia, lub przechwytują wartość, lub obiekt, którego dotyczy, jest utrzymywany przy życiu (i odniesienie może łatwo zwisać).
Jeśli rozumiesz zamknięcie jako odniesienie do funkcji, która ma wbudowany, trwały, ukryte i nierozerwalna kontekst (pamięć, państwa), wtedy tak:
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;
następny zmienia swój stan:
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;
Stan wewnętrzny nie może być odwoływany (dostęp) z zewnątrz.
W zależności od tego, jak to zdefiniujesz, zamknięcie może zawierać odwołanie do więcej niż jednej funkcji lub dwie zamknięcia mogą współdzielić ten sam kontekst, tj. Dwie funkcje mogą współdzielić ten sam stały, ..., stan.
Zamknięcie oznacza niezawierające zmiennych wolnych - jest porównywalne z klasą zawierającą tylko prywatne atrybuty i tylko publiczne metody (metody).
Zachowanie jest podobne do zamknięcia, ale nie powiedziałbym, że jest zamknięcie. – Setepenre
@Stepenre jaka byłaby różnica? – Zrin
To prawie nie wygląda na zamknięcie, to, co tu masz, to tylko obiekt trzymający stan zmodyfikowany przez metodę, plus trochę cukru syntaktycznego, ponieważ jest to "operator()" zamiast jakiejkolwiek innej metody. Niech zwróci wartość lambda zależną od stanu lub parametru metody, a następnie rozmawiamy. – dividebyzero
Tak, to pokazuje, jak można zaimplementować funkcję ze stanem bez użycia funktora.
#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
}
Zapomniałem zmiennego słowa kluczowego, które wprowadziło niezdefiniowane zachowanie (wersja klangowa zwróciła wartość śmieci). Zgodnie z wdrożeniem, zamknięcie działa poprawnie (na GCC i klang)
Aby być naprawdę pewnym, byłoby miło zobaczyć, co stanie się, jeśli uruchomisz 'my_f()' ponownie po 'my_f1()', ponieważ może to być wciąż ta sama zmienna, która została bezpośrednio przypisana do wywołania 'make_my_closure ' '. – dividebyzero
'x' jest wartością tymczasową w' make_my_closure'. Więc IMO nie miałoby sensu. Dodałem sprawę, o którą prosiłeś. Które zachowują się zgodnie z oczekiwaniami – Setepenre
- 1. Czy mamy wzorce projektowe w C++, jakie mamy w java?
- 2. Czy mamy autochomp w Perlu?
- 3. Jak emulować zamknięcia w c
- 4. Czy mamy transakcje w MS-Access?
- 5. Czy mamy metodę "Zawiera" w IEnumerable
- 6. Czy mamy zmodyfikowane wydarzenie canvas w Fabric.js?
- 7. Czy Smalltalk ma zamknięcia?
- 8. Ruby bloki/zamknięcia Java w C
- 9. Wymuszenie zamknięcia połączenia Oracle w C#
- 10. Czy przeprowadzanie sesji zamknięcia transakcji?
- 11. Czy można dokonać rekurencyjnego zamknięcia w Rust?
- 12. Czy mamy danych typu array w SQL Server 2008
- 13. C#: Właściwy sposób zamknięcia SerialPort z WinFormami
- 14. Konwersja bloku Objective-C do zamknięcia Swift
- 15. Zamknięcia w Pythonie
- 16. Składnia zamknięcia w PHPDoc
- 17. Recusive zamknięcia w JavaScript
- 18. Śledzenie zamknięcia
- 19. Późne wiążące zamknięcia Pythona
- 20. Jeśli mamy nieskończoną pamięć, czy nadal potrzebujemy wywoływania?
- 21. Mamy wiele plików migracji bazy danych - czy powinniśmy je zachować?
- 22. gRPC: Jaki jest zalecany sposób zamknięcia asynchronicznego serwera w C++?
- 23. Dlaczego mamy niezmienną pustą mapę?
- 24. Czy mamy nieskompresowaną bibliotekę javascript dla Google Maps API V3
- 25. Czy mamy teraz przenieść naszą aplikację WPF do aplikacji UWP?
- 26. Zamknięcia i uniwersalne kwantyfikacja
- 27. czy możliwe jest wyrwanie się z zamknięcia w groovy
- 28. Czy można zwrócić referencję z zamknięcia w PHP?
- 29. Czy możliwe jest uzyskanie obiektu wywołującego zamknięcia w groovy?
- 30. Czy istnieje sposób zamknięcia instancji Hazelcast w JVM?
Oprócz odpowiedzi poniżej, sprawdź również http://en.cppreference.com/w/cpp/language/lambda, aby uzyskać więcej informacji na temat strony referencyjnej. –
Podobno wiele osób wciąż miesza anonimowe funkcje z zamknięciami. Wciąż nie jest dla mnie jasne, czy C++ 11 rzeczywiście obsługuje zamknięcia, czy tylko anonimowe funkcje ("lambdas"). Nie oczekuję, że C++ będzie obsługiwać rzeczywiste zamknięcie w takim samym sensie, jak w JavaScript, Pythonie, Scali i innych, może to być bardzo zaskakujące. – dividebyzero
Udowadniając, że się mylę, tak, przechwytuje zmienne w kontekście, przez kopiowanie, a nawet przez odniesienie, najwyraźniej jedynym dziwactwem jest to, że nie ma zbierania śmieci ... Nadal chciałbym lepiej zrozumieć, jak to wszystko działa w praktyce http: // pl.cppreference.com/w/cpp/language/lambda – dividebyzero