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

[C++] Wyrażenia lambda a rekurencja

Ostatnio zmodyfikowano 2015-01-25 14:07
Autor Wiadomość
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:
C/C++
class Tree {
public:
    struct T {
        int data;
        T * parent;
        T * left;
        T * right;
    };
    T * root = nullptr;
    void createBST( int n );
    //reszta metod, w tej chwili są nieistotne
};
//...
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 :)
P-125523
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)>.
P-125525
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
C/C++
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
P-125526
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.
P-125527
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:
Błąd visuala
Błąd visuala
 
C/C++
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

@Edit2
W każdym razie wielkie dzięki Fireho za pomoc, teraz wszystko działa :)

Problem rozwiązany, temat zamykam.
P-125528
« 1 »
  Strona 1 z 1