No match for 'operator=='



  • Mahlzeit Leute,

    ich stehe gerade vor einen kleinen Problem und komme nicht drauf was die Lösung ist...

    Ich habe zwei class MyObject und MyObjectNode. In MyObject habe ich eine Liste von MyObjectNode. Diese möchte ich per addNode() ein Element hinzufügen. Dabei soll geprüft werden ob das Element bereits in der List ist. Und da liegt der Fehler. Ich bekomme folgende Meldung:

    In file included from src\main.cpp:1:0:
    lib\MyObejct\src/MyObejct.hpp: In member function 'bool MyObejct<maxElements>::existsNode(MyObejctNode)':
    lib\MyObejct\src/MyObejct.hpp:61:29: error: no match for 'operator==' (operand types are 'MyObejctNode' and 'const MyObejctNode')
                     if(nodes[i] == parentNode) return true;
    *** [.pio\build\nanoatmega328\src\main.cpp.o] Error 1
    

    Folgend der code meiner Obekte:

    MyObject.hpp

    /** @file MyObject.hpp
     * 
     * @brief A description of the module’s purpose. 
     *
     * @par       
     * COPYRIGHT NOTICE: (c) 10.12.2021. All rights reserved.
     */ 
    
    #ifndef MYOBJECT_HPP
    #define MYOBJECT_HPP
    
    #include "Arduino.h"
    #include <stdint.h>
    
    #include "MyObjectNode.hpp"
    
    template <int maxElements> class MyObject {
        private:
              // array of all nodes
            MyObjectNode *nodes;
            int usedNodes = 0;
            int nodeIndex = 0;
            int menuIndex = 0;
            
        public:
            MyObject() {
                nodes = new MyObjectNode[maxElements];
            };
            ~MyObject() {};
            
            void addNode(const MyObjectNode node){
                if( nodeIndex < maxElements) {
                    nodes[nodeIndex++] = node;
                    ++usedNodes;
                }
            };
    
            void addNode(const MyObjectNode parent, const MyObjectNode child){
                if( existsNode(parent)) {
                    Serial.print("Parent exists");
                }
            };
    
            void removeNode();
            bool existsNode(MyObjectNode parentNode) {       
                for (int i=0; i < usedNodes; ++i) {
                    if(nodes[i] == parentNode) return true;
                }
                return false;
            };
    
            void printMenu(){
                Serial.println("menu:");
                Serial.print("usedNodes: ");
                Serial.println(usedNodes);
                
                for (int i=0; i < usedNodes; ++i) {
                    const char* info;
                    nodes[i].getName(info);
                    Serial.println(info);
                }
            }
    
    };
    
    #endif /* MYOBJECT_HPP */
    
    /*** end of file ***/
    

    MyObejctNode.hpp

    /** @file MyObjectNode.hpp
     * 
     * @brief A description of the module’s purpose. 
     *
     * @par       
     * COPYRIGHT NOTICE: (c) 10.12.2021 All rights reserved.
     */ 
    
    #ifndef MYOBJECTNODE_HPP
    #define MYOBJECTNODE_HPP
    
    #include "Arduino.h"
    #include <string.h>
    #include <stdint.h>
    
    class MyObjectNode {
        private:
            const char* name;
            void (*func)(void);   
    
            MyObjectNode *next;
            MyObjectNode *prev;
    
        public:
            MyObjectNode();
            MyObjectNode(const char * const name);
            ~MyObjectNode();
    
            void setName(const char * const name);
            void getName(const char*& info);
    };
    
    #endif /* MYOBJECTNODE_HPP */
    
    

    Vielleicht kann mir da wer helfen.

    Grüße PSP3006


  • Mod

    Die Meldung ist doch recht eindeutig: Du willst zwei MyObejctNode [sic!] vergleichen, aber du erklärst nirgendwo, was "Gleichheit" bedeutet. Eine Vergleichsoperatorfunktion wird nicht automatisch erzeugt, das wäre viel zu häufig nicht das, was man will. Du musst eine Funktion operator== für MyObejctNode schreiben. Wenn dir das komplett unbekannt vorkommt, dann informiere dich über das Stichwort "Operatorüberladung".

    A propos automatisch erzeugte Funktionen: Du definierst in deiner Klasse MyObejctNode eigene Versionen von automatisch erzeugten Funktionen, und ich kann mir kaum vorstellen, dass du das wirklich brauchst. Definierst du da beispielsweise Funktionen, die einfach leer sind? Das sollte dir komisch vorkommen.

    Und umgekehrt bei MyObject machst du es falsch, denn da brauchst du garantiert eigene Versionen dieser Funktionen, da du manuell Ressourcen verwaltest. Siehe Stichworte "RAII" und "Rule of 3" (bzw. heutzutage auch "Rule of 5"). Wieso deine Klassen manuell Ressourcen verwaltet ist hingegen nicht verständlich. Wozu soll das gut sein? Sieht eher so aus, als würdest du nicht wissen, was ein vector ist (Vector zu kennen ist ganz essentiell, dringend angucken!). Der sollte das für dich machen. Normalerweise solltest du so gut wie niemals einen Fall haben, wo du manuell Ressourcen verwaltest. Das nennt man dann "Rule of 0", und ist wie "richtiges" C++ ausschaut.



  • Zum Problem: wann ist denn eine Node gleich einer anderen Node? Dazu müsstest du den operator== für deine MyObjectNode definieren.

    Aber viel spanndender ist:
    Was soll das eigentlich für eine Datenstruktur sein/werden?

    Eine Linked List? (du hast prev- und next-Pointer in der Node definiert)
    Oder ein std::array/vector-Ersatz? (du hast eine getemplatete Größe und erzeugst entsprechend viele Node-Objekte im Freispeicher - machst sozusagen eine Nachteil-Kombination aus einer Mischung von std::array und std::vector)?
    Oder von alles drei Datenstrukturen etwas?

    Noch dazu verwendest du "naked" new[] ohne delete[] (am besten gar kein new benutzen, dann kannst du das delete auch nicht vergessen/falsch machen). Und du beachtest die Rule of 0/3/5 nicht.

    PS:

    void getName(const char*& info);

    Funktionen dürfen auch was zurückgeben. Es benutzt sich auch viel einfacher, wenn man dem getName nicht extra einen Ziel-Pointer übergeben muss.

    Und noch ein PS:
    Der Name MyObject ist nicht hilfreich. Du scheinst hier eine Datenstruktur für mehrere Objekte zu haben. Vielleicht überlegst du dir erstmal, was die Klasse tun soll und benennst sie dann entsprechend. (und der Kommentar "@brief A description of the module’s purpose." hilft natürlich auch nicht weiter...)



  • Die korrekten Header für C++ sind<cstdint> und <string>, nicht <stdint.h> und <string.h>.
    Was mir noch auffällt:

    • rohe char Zeiger zum Ablegen von Zeichenketten sind absolutes no-go, dafür gibt´s std::string
    • getName( const char*& info ) mit void als Rückgabetyp? Warum gibst du nicht direkt name zurück?
    • printMenuals member von MyObject? Das gehört da sicher nicht hin.
    • Übergabe per const value, vermutlich möchtest du Übergabe per const reference. Spätestens hier wird es schwierig zu überprüfen, ob ein Knoten bereits in der Liste vorhanden ist, weil man nicht auf die Identität eines Knoten prüfen kann.

Log in to reply