Wyrażenie Lambda

Wyrażenie Lambda
S5
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:58
0
  1. Napisz funkcję (zwykłą), która przyjmuje parametr typu int. Funkcja powinna zwrócić funkcję lambda która przyjmuje jeden parametr typu int i zwraca sumę z wartości przekazanych do zwykłej funkcji i funkcji lambda.
    *Chciałbym się upewnić czy jest dobrze i co dalej zrobić ?
Kopiuj
#include <iostream>

using namespace std;

int add(int x , int f){return x+f;}

auto f = [](int xx){return xx;};

Patryk27
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
3

Napisz funkcję (zwykłą), która przyjmuje parametr typu int.

Gdzie masz tę funkcję?


enedil
  • Rejestracja:prawie 12 lat
  • Ostatnio:dzień
  • Postów:1027
2

W skrócie, nie masz nic w tym dobrze. W szczególności, żadna z funkcji, które napisałeś nie zwraca funkcji lambda.

S5
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:58
0
enedil napisał(a):

W skrócie, nie masz nic w tym dobrze. W szczególności, żadna z funkcji, które napisałeś nie zwraca funkcji lambda.

funkcja::
int add(int x , int f){return x+f;}

S5
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:58
1
Patryk27 napisał(a):

Napisz funkcję (zwykłą), która przyjmuje parametr typu int.

Gdzie masz tę funkcję?
Funkcja::
int add(int x , int f){return x+f;}

Patryk27
która przyjmuje parametr typu int - Twoja przyjmuje dwa inty.
lion137
  • Rejestracja:ponad 8 lat
  • Ostatnio:32 minuty
  • Postów:4945
1

enedil
  • Rejestracja:prawie 12 lat
  • Ostatnio:dzień
  • Postów:1027
2
sssebastianb5 napisał(a):
enedil napisał(a):

W skrócie, nie masz nic w tym dobrze. W szczególności, żadna z funkcji, które napisałeś nie zwraca funkcji lambda.

funkcja::
int add(int x , int f){return x+f;}

No nie zwraca funkcji lambda, zwraca sumę liczb, a nie funkcję.

S5
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:58
0
enedil napisał(a):
sssebastianb5 napisał(a):
enedil napisał(a):

W skrócie, nie masz nic w tym dobrze. W szczególności, żadna z funkcji, które napisałeś nie zwraca funkcji lambda.

funkcja::
int add(int x , int f){return x+f;}

No nie zwraca funkcji lambda, zwraca sumę liczb, a nie funkcję.

czyli ,co mam napisać funkcję lambda w następujący sposób ?

Kopiuj
auto l = [] (int x, int y) { return x + y; };

enedil
  • Rejestracja:prawie 12 lat
  • Ostatnio:dzień
  • Postów:1027
1

Nie, dalej nie zwracasz żadnej funkcji lambda, tylko jakąś sumę liczb.

S5
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:58
0
Kopiuj
auto add() -> decltype ([](int x) -> int)
{
    return [](int x) { return x; }
}

chodzi może o ten zapis ?

enedil
  • Rejestracja:prawie 12 lat
  • Ostatnio:dzień
  • Postów:1027
1

Coś tego typu, tylko jeszcze pozostaje zgodność z resztą założeń zadania (np. fajnie żeby funkcja add coś dodawała gdzieś).
Możesz również pominąć jawną deklarację typu zwracanego (z pewnością jeśli użyjesz -std=c++2a -fconcepts, nie wiemczy bez tego działa)

edytowany 1x, ostatnio: enedil
S5
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:58
0

co powiesz teraz ?

Kopiuj
	auto add() -> decltype ([](int x ,int y) -> int)
{
    return [](int x,int y) { return x+y; };
}
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
3

A nie chodzi o jakieś:

Kopiuj
auto add(int x){
    auto fun = [x] (int y) { return x + y; };
    return fun;
}

(pewnie trochę zła składnia ale nie umiem w lambdy w c++)
edit: fixed
Masz funkcje add która dla argumentu int zwraca nową funkcje, która dla argumentu int zwraca sumę tych 2 intów.


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 6x, ostatnio: Shalom
enedil
składnia poprawna, ale te nawiasy kwadratowe to capture list, lista zmiennych dostępnych w domknięciu. U Ciebie jest pusta, a miała zawierać x.
Shalom
fixed :)
enedil
Swoją drogą, zachowanie lambd jest śmieszne, bo w zależności od wielkości zmiennych przechwytywanych, na potrzeby ich zachowania odbędzie się alokacja na stercie bądź nie, ciekawe czy dało by się robić jakieś interesujące memory corruption w programie intensywnie korzystającym z lambd
Shalom
@enedil: jakimś use after free mógłbyś pewnie zmienić takie juz capturowane wartości, ale sam fakt używania lambd raczej niczego sam z siebie nie psuje, musiałbyś mieć jakąś podatność, którą lambdy pozwolą wykorzystać.
S5
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:58
0

wiesz co ale pokazuje mi jakiś komunikat o błędzie w twoim kodzie

lion137
Dziwne, bo to powinno być OK
enedil
  • Rejestracja:prawie 12 lat
  • Ostatnio:dzień
  • Postów:1027
0

No to czas na debugowanie, jaki błąd dostajesz?

S5
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:58
0

[Error] expected '}' at end of input

Kopiuj
auto add(int x){
    auto fun = [x] (int y) { return x + y; };
    return fun;
}
edytowany 1x, ostatnio: sssebastianb5
enedil
To źle skopiowałeś
Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
S5
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:58
0
Shalom napisał(a):

@sssebastianb5:

https://ideone.com/JKDDM2

u mnie działa

*mam dalej błąd po skopiowaniu kodu:

,, [Error] 'add' function uses 'auto' type specifier without trailing return type""

MarekR22
Funkcja z auto i bez -> na końcu to C++14.
ledi12
  • Rejestracja:prawie 6 lat
  • Ostatnio:2 miesiące
  • Lokalizacja:Wrocław
2
Kopiuj
auto first(int x) {
    auto lambda = [x](int y){ return x+y; };
    return lambda;
};

auto func = first(2);
auto lambda = func(6);

cos takiego ?
@Edit


Robię http response status cody w martwych ciągach
edytowany 1x, ostatnio: ledi12
enedil
nie o to chodzi
enedil
A teraz wygląda dokładnie tak samo jak u Shaloma
Tasmanian Devil
Hej! Twój post prawdopodobnie zawiera niesformatowany kod. Użyj znaczników ``` aby oznaczyć, co jest kodem, będzie łatwiej czytać. (jestem botem, ta akcja została wykonana automatycznie, prawdopodobieństwo 0.9921184)
enedil
  • Rejestracja:prawie 12 lat
  • Ostatnio:dzień
  • Postów:1027
1
sssebastianb5 napisał(a):
Shalom napisał(a):

@sssebastianb5:

https://ideone.com/JKDDM2

u mnie działa

*mam dalej błąd po skopiowaniu kodu:

,, [Error] 'add' function uses 'auto' type specifier without trailing return type""

https://stackoverflow.com/questions/44798728/warning-function-uses-auto-type-specifier-without-trailing-return-type

przełącz wersję języka na nowszą, co najmniej c++14

S5
  • Rejestracja:około 5 lat
  • Ostatnio:ponad 4 lata
  • Postów:58
0
enedil napisał(a):
sssebastianb5 napisał(a):
Shalom napisał(a):

@sssebastianb5:

https://ideone.com/JKDDM2

u mnie działa

*mam dalej błąd po skopiowaniu kodu:

,, [Error] 'add' function uses 'auto' type specifier without trailing return type""

https://stackoverflow.com/questions/44798728/warning-function-uses-auto-type-specifier-without-trailing-return-type

przełącz wersję języka na nowszą, co najmniej c++14

*Super wszystko działa wielkie dzięki :)

edytowany 1x, ostatnio: Shalom
lion137
To wklej jeszcze działający kod na forum, dla potomności:)
enedil
@lion137: wszystko działało u Shaloma, tylko były złe flagi kompilacji wybrane
lion137
  • Rejestracja:ponad 8 lat
  • Ostatnio:32 minuty
  • Postów:4945
2

tak tylko zostawiam:

Kopiuj
# dummy lambda discussion:)

def f(x):
	return lambda y: y + x


print(f(41)) # function bla bla bla
print(f(41)(1)) # 42

Zobacz pozostałe 2 komentarze
Patryk27
tak tylko zostawiam: let f = x: y: x + y; in f 41 1 (nix) :-P
lion137
Very nice, to jeszcze jest czytalne, zaraz to zobfuskują Haskellem:))
Shalom
OCaml ma automatyczny currying, haskell chyba też? Więc tam w ogóle nie trzeba nic robić, ot piszesz funkcje która przymuje dwa argumenty i zwraca ich sumę i już.
enedil
Drobne schody w podejściu Ocamlowo Haskellowym przychodzą jak dana funkcja nie jest przemienna, i nie chodzi o związanie pierwszego argumentu.
KamilAdam
@enedil: czy funkcja flip rozwiązuje twoje problemy? i wtedy np. rdiv = flip div a potem divBy2 = rdiv 2
LI
LI
  • Rejestracja:prawie 5 lat
  • Ostatnio:prawie 4 lata
  • Postów:98
1

Jest taka prezentacja "Fun with Lambdas": https://www.slideshare.net/SumantTambe/fun-with-lambdas-c14-style

Krok po kroku pokazuje coraz to bardziej pokręcone lambdy, ta na slajdzie 19 to już prawie-to-o-co-tu-chodzi, bo zapamiętuje parametr, trzeba by tylko dodawanie dołożyć.

TomaszLiMoon
  • Rejestracja:prawie 10 lat
  • Ostatnio:około 2 godziny
  • Postów:530
2

Tutaj przykład zwracanej lambdy w ogólnej formie ( C++17 )

Kopiuj
template< typename ...Arg >
auto sum( Arg&&... args )
{
    return  [ args = std::make_tuple( std::forward<Arg>(args) ... ) ]( auto a )
            {
               return a + std::apply( [](auto&& ... args ){ return (args+...); } , std::move(args) );
            };
}
......
std::cout << sum(41)(1) << std::endl; // = 42
std::cout << sum(1,2,3)(-1) << std::endl; // = 5
std::cout << sum(1.6,-2.1,3)(-0.01) << std::endl; // = 2.49
std::cout << sum('b',-'a')(0) << std::endl; // = 1
std::cout << sum(0.01,'c',-34.6,0.6,8.7)(20.0) << std::endl;  // = 93.71
std::cout << sum(" is"s, " my"s, " name"s)("This"s) << std::endl; // = "This is my name"
edytowany 2x, ostatnio: TomaszLiMoon
Spearhead
  • Rejestracja:prawie 6 lat
  • Ostatnio:17 minut
  • Postów:1002
1

A ja wysmażyłem coś takiego (fold expressions for the win):

Kopiuj
#include <iostream>

auto sum() {
    return []<typename ...Args>(Args&&... args){return (args + ...);};
}

int main()  {
    std::cout << sum()(1, 2, 3, 4) << std::endl;
}
Kopiuj
$ g++ test.cpp -o test -std=c++17
$ ./test 
10

Z parametrem to

Kopiuj
#include <iostream>

template <class T>
auto sum(T i) {
    return [i]<typename ...Args>(Args&&... args){return (args + ... + i);};
}

int main()  {
    std::cout << sum(10)(1, 2, 3, 4) << std::endl;
}
Kopiuj
$ g++ test.cpp -o test -std=c++17
$ ./test 
20

Albo na całego:

Kopiuj
#include <iostream>

template <class ...T>
auto sum(T&&... t) {
    return [t...]<typename ...Args>(Args&&... args){return (args + ... + (t + ...));};
}

int main()  {
    std::cout << sum(10, 10, 10)(1, 2, 3, 4) << std::endl;
}
Kopiuj
$ g++ test.cpp -o test -std=c++17
$ ./test 
40
edytowany 4x, ostatnio: Spearhead
kq
Tak szczerze to nie widzę sensu wielokrotnego wyliczania sumy parametrów (tu i w poprzednim poście), przecież ona jest stała.
MarekR22
ale tu nie chodzi o sens, ale o szpan.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.