Zuweisungsoperator als member



  • Hallo!

    Habe folgende Klasse:

    template <typename TValue, typename TPred = std::less<TValue> >
    class BinarySearchTree {
    
    	struct TNode {
    		TValue value;
    		TNode *pLeft;
    		TNode *pRight;
    	};
    
    public:
    
    	BinarySearchTree();
    	BinarySearchTree(BinarySearchTree<TValue, TPred> const &tree);
    	BinarySearchTree<TValue, TPred> &operator=(BinarySearchTree<TValue, TPred> const &tree);
    	~BinarySearchTree();
    
    	bool Insert(TValue const &value); // returns false if already contained
    
    	template <typename TVisitor> void VisitPreOrder(TVisitor visitor) const;
    	template <typename TVisitor> void VisitInOrder(TVisitor visitor) const;
    	template <typename TVisitor> void VisitPostOrder(TVisitor visitor) const;
    
    private:
    	TNode *pRoot;
    
    ...
    
    	template <typename TVisitor> void VisitInOrder  (TVisitor visitor, TNode const * const pRoot) const;
    ...
    
    	// ... helper methods ...
    };
    

    (die schnittstelle darf nicht geändert werden)
    wenn ich die operatorüberladung so mache (genau wie im ctor), dann:

    if (this != &tree) 
                    {
    		tree.VisitInOrder(Insert);
    		}
    	return *this;	//Referenz auf das Objekt selbst
    

    schreit der compiler:
    [quote]

    Error 1 error C3867: 'BinarySearchTree<TValue>::Insert': function call missing argument list; use '&BinarySearchTree<TValue>::Insert' to
    create a pointer to member 70
    Error 2 error C2780: 'void BinarySearchTree<TValue>::VisitInOrder(TVisitor,const BinarySearchTree<TValue>::TNode *const ) const' : expects 2 arguments - 1 provided 70

    luat googlesuche hat das anscheiend was mit binary, unary zum tun, aber ich weiß nicht wieso und ich weiß nicht wie ich das ändern muss
    daher brauche ich wieder einaml eure hilfe

    mfg
    ACnut


  • Mod

    Soll vermutlich soetwas wie

    tree.VisitInOrder(std::bind(&BinarySearchTree::Insert,this,std::placeholders::_1));
    

    sein.



  • wow es funktioniert.
    aber wieso was tu ich da wie genau funktioniert dieses bind? und wodurch wird placeholder ersetzt?



  • Die Funktion erwartet eine aufrufbare Einheit. Mit der macht die so etwas:

    visitor(some_value);
    

    , vermute ich.
    Du übergibst ihr eine Memberfunktion.
    Eine Memberfunktion kann man aber nicht wie oben aufrufen, sondern man muss

    objekt.visitor(some_value);
    

    schreiben.
    Jetzt kann man aber zum Glück tricksen. Eine Memberfunktion erwartet nämlich intern an erster Stelle einen Zeiger auf ein Objekt - den this-Zeiger.
    std::bind() nimmt sich nun die Memberfunktion und liefert ein Funktionsobjekt zurück.
    Die Funktion erwartet zwei Argumente und liefert bool zurück - an das erste Objekt ist allerdings fest das aktuelle Objekt gebunden, an das zweite nur ein Platzhalter, d.h., dass man den operator() mit nur einem Argument aufrufen kann, nämlich dem, wo der Platzhalter ist. Deshalb ist der erstgenannate Aufruf gültig.



  • kannst du mir bitte das mit dem platzhalter noch einmal genauer erkären bzw. das hier:

    dass man den operator() mit nur einem Argument aufrufen kann, nämlich dem, wo der Platzhalter ist.



  • Der Platzhalter gibt einfach nur an, welche Argumente der Funktion auch wirklich variabel bleiben und an den operator() übergeben werden müssen.
    Beispiele:

    void func(int a, int b) {...}
    
    // kein bind
    func(5, 2); // 2 Argumente
    
    auto f1 = std::bind(func, std::placeholders::_1, std::placeholders::_2); // zwei Platzahler
    f1(5, 2); // 2 Argumente
    
    auto f2 = std::bind(func, 1, std::placeholders::_1) // Argument a vorbelegt, b Platzhalter
    f2(2); // 1 Argument, a = 1, b = 2
    
    auto f3 = std::bind(func, std::placeholders::_1, 1) // Argument b vorbelegt, a Platzhalter
    f3(5); // 1 Argument, a = 5, b = 1
    
    auto f4 = std::bind(func, 1, 2); // alles
    


  • ok verstehe, durch das od eoben erhalten wir daher eine unäre funktion
    vielen vielen dank


Log in to reply