Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Wyrazenia lambda i jak je przekazywac ?

Ostatnio zmodyfikowano 2017-03-07 17:09
Autor Wiadomość
en2senpai
Temat założony przez niniejszego użytkownika
Wyrazenia lambda i jak je przekazywac ?
» 2017-03-07 13:03:10
Witam,

Chce stworzyc mechanizm obslugi eventow, tak aby uzytkownik sam mogl wytworzyc wlasny, dowolny warunek bazujacy na spelnieni podanego przez niego wyrazenia.

Czy zasadnym jest uzycie do tego celu wyrazen lambda? np:

C/C++
int a = 3;
int b = 4;
auto lambda =[ & a, & b ]()->bool { return a == b ? true: false; };

Czy jest mozliwosc zapisania podanego wyrazenia lambda w pamieci, tak aby okresowo moc je sprawdzac (klasa nadrzedna zawierajaca tablice eventow, sprawdzajaca czy zachodzi podany przez uzytkownika warunek)?

Na capture list wyrazenia sa referencje do zmiennych a i b, wiec w ramie defacto tworzy sie struktura zawierajaca 2 adresy

C/C++
( uint32_t * ) & lambda // zwraca 32 bitowy adres gdzie w pamieci RAM znajduja sie 2 adresy zmiennych z warunku

Gdzie jest natomiast adres samej funkcji ? (zapisany w pamieci ROM)
Jakiego typu dokladnie jest w tym wypadku lambda?
Mozna stworzyc strukture, ktora bedzie przechowywala wszystkie informacje niezbedne do pozniejszego sprawdzenia warunku ?
Finalnie czy mozna je przekazywac do funkcji (widzialem podejscia z szablonami), ktora bedzie w pewien sposob uniwersalna i dokona zapisania warunku (kazdego, zakladajac ze kazda inna lambda bedzie juz innym typem)
P-158652
Monika90
» 2017-03-07 13:44:48
Wartości różnych wyrażeń lambda można trzymać w std::vector<std::function<F>>
gdzie F to typ postaci TypZwracay (Arg1, Arg2, itd...) w twoim przykładzie byłby to bool ()
P-158653
en2senpai
Temat założony przez niniejszego użytkownika
» 2017-03-07 14:02:26
Ciekawa propozycja, gdzies juz ja widzialem. Mozna jednak uniknac std::function? Narazie zrobilem to tak.

Klasa event.h

C/C++
template < class T >
class event
{
    uint32_t * _address;
   
public:
    event( uint32_t * address );
    ~event();
   
    bool check();
};

template < class T > event < T >::event( uint32_t * address )
{
    _address = address;
}

template < class T > event < T >::~event()
{
   
}

template < class T > bool event < T >::check()
{
    T temp = *( T * ) _address;
    return temp();
}

Natomiast do testow mam cos takiego:

C/C++
int a = 3;
int b = 4;
volatile bool wynik;

auto warunek1 =[ & a, & b ]()->bool { return a == b ? true: false; };
auto warunek2 =[ & a, & b ]()->bool { return a < b ? true: false; };

event < decltype( warunek1 ) > event1(( uint32_t * ) & warunek1 );
event < decltype( warunek2 ) > event2(( uint32_t * ) & warunek2 );


wynik = event1.check(); // zwraca 0 - zmienne a i b nie sa rowne
wynik = event2.check(); // zwraca 1 - zmienna a jest mniejsza od zmiennej b

b = 3;

wynik = event1.check(); // zwraca 1 - zmienne a i b sa rowne
wynik = event2.check(); // zwraca 0 - zmienna a nie jest mniejsza niz zmienna b


P-158654
Monika90
» 2017-03-07 14:23:37
To są jakieś przedziwne kombinacje, bo ten sam efekt można osiągnąć prościej
C/C++
template < class Func >
struct func_ref
{
    Func & f;
    bool check() const { return f(); }
};

int main()
{
    int a = 3;
    int b = 4;
    volatile bool wynik;
   
    auto warunek1 =[ & a, & b ] { return a == b; };
    auto warunek2 =[ & a, & b ] { return a < b; };
   
    func_ref < decltype( warunek1 ) > event1 { warunek1 };
    func_ref < decltype( warunek2 ) > event2 { warunek2 };
   
   
    wynik = event1.check(); // zwraca 0 - zmienne a i b nie sa rowne
    wynik = event2.check(); // zwraca 1 - zmienna a jest mniejsza od zmiennej b
   
    b = 3;
   
    wynik = event1.check(); // zwraca 1 - zmienne a i b sa rowne
    wynik = event2.check(); // zwraca 0 - zmienna a nie jest mniejsza niz zmienna b
}

A jeżeli chcesz żeby zmienne event1 i evet2 były tego samego typu, to musisz użyć type erasure i do tego właśnie służy std::function
P-158655
en2senpai
Temat założony przez niniejszego użytkownika
» 2017-03-07 14:59:19
Wlasnie chodzi o to zeby wszystkie eventy mialy ten sam typ, aby mozna bylo zrobic ich zbior (teraz trzeba bedzie zrobic klase bazowa, po ktorej klasa event dziedziczy i nie jest szablonowa, nastepnie ich tablice i zapisywac wskazniki na eventy - pokrecone aczkolwiek do tego zmierzam)
P-158657
en2senpai
Temat założony przez niniejszego użytkownika
» 2017-03-07 16:55:09
Delikatnie uproscilem klase

C/C++
template < typename T > class event
{
    T * fun;
   
public:
    event( T & l );
    ~event();
   
    bool check();
   
};

template < typename T >
event < T >::event( T & l )
{
    fun = & l;
}

template < typename T >
event < T >::~event()
{
   
}

template < class T > bool event < T >::check()
{
    T temp = * fun;
    return temp();
}

i teraz mozna powolac obiekt

C/C++
event < decltype( warunek1 ) > event1( warunek1 );

Mozna jakos poprawic metode check()? Tak zeby tylko wykozystac posiadany wskaznik, nie robic kopiowania do obiektu temp ?

P-158663
Monika90
» 2017-03-07 17:09:12
C/C++
return( * fun )();
P-158664
« 1 »
  Strona 1 z 1