#cpp #cpp17 #programowanie czy istnieje sposób na odwołanie się do lambdy w jej deklaracji? Chcę zrobić funkcję która pozwoli mi zapytać użytkownika czy nie chce spróbować się połączyć z bazą ponownie, jeżeli ta wywali wyjątek.
@Capt_S: nie, ale da się to zrobić lambdą wyższego rzędu, która zwraca lambdę wywołującą przekazaną lambdę jako pierwszy argument, jak znajdę do tam linka do moich wypocin.
@Capt_S: Ok znalazłem, ale widzę, że w twoim kodzie nie działa coś zupełnie innego. Po pierwsze nie używaj [&], praktycznie nigdy nie używaj. Jedyny wyjątek to jak chcesz ją używać w miejscu, bo całe szczęście, że to jest korutyna z C++20, ale jak jej obiekt się przeniesie, to już bieda może być. Staraj się używać auto do lokalnych lambd, jeśli tylko możesz, a unikać std::function, chyba że jest potrzebne
@lionbest: widzę, że inaczej to zrobiłeś. Czy twoje rozwiązanie z zagnieżdżoną lambdą jest w czymś lepsze od odwołania do samej siebie które ja zrobiłem?
@Capt_S: Po pierwsze masz referencje do obiektu std::function na stosie... wróć, w korutynie, ale przypuśćmy, że na stosie, to jak ten obiekt wyjdzie ze scope, to przestanie działać. Wartości std::function nie skopiujesz, bo jeszcze jej nie ma, przed definicją lambdy, jedyny sposób to zrobić std::shared_ptr na std::function. Ostatnią najmniej istotną sprawą jest sam fakt optymalizacji. Wywołanie std::function nie może zostać zinlinowane i zoptymalizowane. Z kolei optymalizacja wywołania lambdy przekazanej jako
@lionbest: ok, postaram się to poprawić na twój sposób, bo to moze być powodem mojego błędu w sumie... ale sądziłem, że nie wychodzę ze scope z tym, że to wszystko async na którym się nie znam więc może i wychodzę. ;c
@Capt_S: 1) Możesz dać globalnie np constexpr auto LambdaFixture = [] ( auto&& f ) { albo constexpr auto YCombinator = [] (auto&& f) { . A jak nie chcesz na lambdach to kolega wyzej przesłał link do stackoverflow i ta jedna odpowiedź robi dokładnie to samo Poza tym, to jest warning a nie błąd.
@lionbest: tzn. ja skopiowałem cały twój kod, nic nie zmieniłem poza zamianą "return a + b" na "cout << a + b". Kwestia kompilatora?
A co do tego, że to warning, a nie err to wiem tylko, że chciałem się dowiedzieć czy to celowo. Tzn. jak mam to żółte podkreślenie, to nie ma to nic wspólnego z pierwotnie zadeklarowanym fix(), tak?
@Capt_S: Faktycznie to jest jakiś problem MSVC, że nie może używać lambdy, wywołanej na samej sobie. Musisz chyba jednak skorzystać z rozwiązania na stackoverflow. Jest dokładnie adekwatne do tego rozwiązania, tylko zaimplementowane bez lambd.
@lionbest: ... xD to co ja mam zrobić? :D I nie działa na MSVC (jak twój) czy w ogóle? A ja już czytam tam komentarz
The Y-combinator certainly is the way to go. But you really should add a non-const overload in case the provided function-object has a non-const call-operator. And use SFINAE and computed noexcept for both. Also, there's no need for the maker-function in C++17 anymore.
@Capt_S: Doszedłem, czemu nie działa. Nie lubi lambdy zwracającej auto. https://godbolt.org/z/7UV9uZ Dokładniej to nie wiem czemu, ale zachowanie zupełnie różne od gcc.
@lionbest: udało mi się samemu! :D Zrobiłem CallCritical memberem MainPage i przekazałem const& do std::function i działa! Ten błąd:
Exception thrown at 0x00007FFCE037A839 (KernelBase.dll) in NOVATeacher.exe: WinRT originate error - 0x80004005 : 'The window has already been destroyed.'.
Pozostał... ale działa co ma działać. Ale dla czystości, pokombinuję jeszcze co z tym zrobić... :)
I to chyba nie jest błąd tylko info odnośnie sql_exception, że w czasie raportowania nie ma już okna które wywołało funkcję i w tym miejscu byłby po prostu id okna... ale nie ejstem pewien
@Capt_S: No nie stery czasami tak jest, że coś lepiej zrobić na około i się okazuje, że tak w sumie powinno być. Finalnie działająca wersja pod MSVC z konstruktorem i automatyczną dedukcją szablonu https://godbolt.org/z/Q-RxsY Co do SFINAE to na razie nie ma się co przejmować jak nie korzystasz z noexcept.
@lionbest: czy mój sposób jest niedobry lub z jakiegoś powodu gorszy? W czym mi pomoże użycie tego y_combinatora? Bo nie za bardzo wiem jak go dostosować do tego co mam i jaki problem rozwiąże.
Po pierwsze nie używaj
[&]
, praktycznie nigdy nie używaj. Jedyny wyjątek to jak chcesz ją używać w miejscu, bo całe szczęście, że to jest korutyna z C++20, ale jak jej obiekt się przeniesie, to już bieda może być.Staraj się używać auto do lokalnych lambd, jeśli tylko możesz, a unikać
std::function
, chyba że jest potrzebneWartości
std::function
nie skopiujesz, bo jeszcze jej nie ma, przed definicją lambdy, jedyny sposób to zrobićstd::shared_ptr
nastd::function
.Ostatnią najmniej istotną sprawą jest sam fakt optymalizacji. Wywołanie
std::function
nie może zostać zinlinowane i zoptymalizowane.Z kolei optymalizacja wywołania lambdy przekazanej jako
1)
auto comb = [](auto&& f) {
auto fix = [f](auto&& g) {
Mogę podmienić nazwę zmiennej na
_fix
czy to z jakiegoś powodu celowe?2)
return f(f, x - 1) + f(f, x - 2);
constexpr auto LambdaFixture = [] ( auto&& f ) {
albo
constexpr auto YCombinator = [] (auto&& f) {
.A jak nie chcesz na lambdach to kolega wyzej przesłał link do stackoverflow i ta jedna odpowiedź robi dokładnie to samo
Poza tym, to jest warning a nie błąd.
Co do kolejny podpunktów to coś źle użyłeś.
A co do tego, że to warning, a nie err to wiem tylko, że chciałem się dowiedzieć czy to celowo. Tzn. jak mam to żółte podkreślenie, to nie ma to nic wspólnego z pierwotnie zadeklarowanym fix(), tak?
i chciałem pytać
Dokładniej to nie wiem czemu, ale zachowanie zupełnie różne od gcc.
Ten błąd:
Pozostał... ale działa co ma działać. Ale dla czystości, pokombinuję jeszcze co z tym zrobić... :)
Finalnie działająca wersja pod MSVC z konstruktorem i automatyczną dedukcją szablonu https://godbolt.org/z/Q-RxsY
Co do SFINAE to na razie nie ma się co przejmować jak nie korzystasz z
noexcept
.