[C++] Wyrażenia lambda a rekurencja
Ostatnio zmodyfikowano 2015-01-25 14:07
Kopczak1995 Temat założony przez niniejszego użytkownika |
[C++] Wyrażenia lambda a rekurencja » 2015-01-25 13:26:53 Witam. Bawiłem się nieco z wyrażeniami lambda i natrafiłem na jeden problem. Zrobiłem sobie klasę dla drzewa binarnego i chciałem dodawać n elementów do niego. Najpierw całość uczyniłem zwyczajnie, bez wyrażenia lambda. Opierało się to na 2 metodach: pierwsza z nich pytała użyszkodnika o to ile elementów chce dodać, po czym w pętli odpalałem drugą odpowiednią liczbę razy. Wszystko śmigało jak ta lala :P Jednak gdy tą 2 metodę przerobiłem na wyrażenie lambda i wstawiłem do wnętrza pierwszej to pojawił się problem... Visual zaczął krzyczeć coś takiego: Error: a variable declared with auto specifier cannot appear in its own initializer
Oto moja klasa i potrzebna definicja metody: class Tree { public: struct T { int data; T * parent; T * left; T * right; }; T * root = nullptr; void createBST( int n ); };
void Tree::createBST( int n ) { auto addBST =[]( T *& root, int & x )->void { if( root != nullptr ) { if( x > root->data ) addBST( root->right, x ); else addBST( root->left, x ); } else { T * nowy = new T; nowy->parent = root; nowy->left = nullptr; nowy->right = nullptr; nowy->data = x; root = nowy; } }; cout << "Zadanie 2" << endl << "Elementy wylosowane i wprowadzone do drzewa BST:" << endl; for( int i = 0, x = rand() % 11; i < n; i++, x = rand() % 11 ) { addBST( this->root, x ); cout << x << " "; } cout << endl; }
Powiecie mi, jak można obejść/rozwiązać ten problem? Da się w ogóle wykorzystać rekurencję w wyrażeniach lambda? Będę wdzięczny za wszelką pomoc :) |
|
Fireho |
» 2015-01-25 13:45:36 Da się, tylko nie możesz użyć typu auto. Musisz dołączyć bibliotekę <functional> i zamienić typ auto na std::function<TYP_ZWRACANEJ_WARTOSCI(TYP_ARGUMENTU_1, TYP_ARGUMENTU_2, ... TYP_ARGUMENTU_N)>. |
|
Kopczak1995 Temat założony przez niniejszego użytkownika |
» 2015-01-25 13:52:39 Hmmm... Ogólnie spoko ale pojawił się nowy problem :P void Tree::createBST( int n ) { function < void( Tree::T, int & ) > addBST =[]( T *& root, int & x )->void { if( root != nullptr ) { if( x > root->data ) addBST( root->right, x ); else addBST( root->left, x ); } else { T * nowy = new T; nowy->parent = root; nowy->left = nullptr; nowy->right = nullptr; nowy->data = x; root = nowy; } }; cout << "Zadanie 2 - tworzenie" << endl << "Elementy wylosowane i wprowadzone do drzewa BST:" << endl; for( int i = 0, x = rand() % 11; i < n; i++, x = rand() % 11 ) { addBST( this->root, x ); cout << x << " "; } cout << endl; }
Oto co teraz krzyczy Visual: Error: an enclosing-function local variable cannot be referenced in a lambda body unless it is in the capture list
|
|
Fireho |
» 2015-01-25 14:00:47 W nawiasach kwadratowych na początku lambdy musisz dopisać &addBST. Nie przeczytałem dokładnie pierwszego wyniku w Google. |
|
Kopczak1995 Temat założony przez niniejszego użytkownika |
» 2015-01-25 14:07:11 Teraz jest jeszcze lepiej :D Znowu jak najadę na rekurencyjne wywołanie addBST to mam coś takiego: void Tree::createBST( int n ) { function < void( Tree::T, int & ) > addBST =[ & addBST ]( T *& root, int & x )->void { if( root != nullptr ) { if( x > root->data ) addBST( root->right, x ); else addBST( root->left, x ); } else { T * nowy = new T; nowy->parent = root; nowy->left = nullptr; nowy->right = nullptr; nowy->data = x; root = nowy; } }; cout << "Zadanie 2" << endl << "Elementy wylosowane i wprowadzone do drzewa BST:" << endl; for( int i = 0, x = rand() % 11; i < n; i++, x = rand() % 11 ) { addBST( this->root, x ); cout << x << " "; } cout << endl; }
@Edit, dobra mój błąd :P Źle napisałem w 1 linijce, tak powinno być: function < void( T *&, int & ) > addBST =[ & addBST ]( T *& root, int & x )->void @Edit2W każdym razie wielkie dzięki Fireho za pomoc, teraz wszystko działa :) Problem rozwiązany, temat zamykam. |
|
« 1 » |