[gelöst] std::vector - Compilerfehler bezüglich Operator!=



  • Sollte ja, da "Event.h" vor <vector> inkludiert wird.

    Hier die Fehlerstellen laut Compiler:

    // TEMPLATE FUNCTION fill
    template<class _FI, class _Ty> inline
    	void fill(_FI _F, _FI _L, const _Ty& _X)
    	{for (; _F != _L; ++_F)
    		*_F = _X; }
    
    // TEMPLATE FUNCTION copy_backward
    template<class _BI1, class _BI2> inline
    	_BI2 copy_backward(_BI1 _F, _BI1 _L, _BI2 _X)
    	{while (_F != _L)
    		*--_X = *--_L;
    	return (_X); }
    


  • Kann es sein, das CEvent selbst Objekte von Klassen benutzt, denen operator== fehlt?



  • Das schaut so aus als ob er Poitner auf CEvent nicht mehr vergleichen kann. Da scheinst du an anderer Stelle irgendwas hässliches angestellt zu haben. Versuch am besten mal mit einer leeren klasse anzufangen und dann nach und nach die gesamte Funtkionalität hinzuzufügen. Compiliere jedes mal, irgendwann fängt der Compiler dann an...



  • Merkwürdig. Laut Fehlermeldung

    c:\programme\microsoft visual studio\vc98\include\xutility(39) : error C2582: Die Funktion für Operator '!=' ist in '<unbekannt>' nicht verfügbar
    c:\programme\microsoft visual studio\vc98\include\vector(170) : Siehe Verweis auf Instantiierung der kompilierten Funktionsvorlage 'void __cdecl std::fill(class CEvent *,class CEvent *,const class CEvent &)'

    wird das std::fill -Funktionstemplate mit den Typen CEvent* und const CEvent& instanziiert. Doch der Compiler findet den eingebauten Zeiger-Vergleichsoperator nicht?

    Das "<unbekannt>" in der Fehlermeldung ist wahrscheinlich auch nicht gut. Funktioniert deine CEvent-Klasse, wenn du sie ausserhalb des std::vector s verwendest?



  • Tachyon schrieb:

    Kann es sein, das CEvent selbst Objekte von Klassen benutzt, denen operator== fehlt?

    Ja ich habe eine Klasse, die zuvor in Event.cpp definiert war, in eine eigene Header-Datei gesteckt und dabei diese Klasse "uncopyable" gemacht. Dafür nutze ich aber Objekte dieser Klasse nur mittels boost::shared_ptr.



  • Nexus schrieb:

    Funktioniert deine CEvent-Klasse, wenn du sie ausserhalb des std::vector s verwendest?

    Nee, jetzt nicht mehr. Zuweisungen sind nicht mehr möglich.

    Die Klasse CEvent:

    //...
    #include "smart_ptr.hpp" // boost::shared_ptr (Ersatz für TR1-Standard)
    
    class CEventHandle;
    typedef boost::shared_ptr<CEventHandle> EVENT_HANDLE;
    
    class CEvent{
    
    		// Konstruktor/Destruktor //
    	public:
    		explicit CEvent(bool autoReset = true);		 // Event vollständig neu erzeugen
    		explicit CEvent(const EVENT_HANDLE& handle); // Event basierend auf bestehenden HANDLE
    		virtual ~CEvent();
    
    		// Methoden //
    	public:
    		void Set();        // Setze Event
    		void Reset();      // Event zurück setzten
    		void Wait() const; // Warte auf Event
    		bool Wait(unsigned long timeout) const; // Warte auf Event (false = Timeout, true = Event)
    		const EVENT_HANDLE GetHandle() const;   // Liefert Event-Handle
    		bool equal(const CEvent& otherEvent) const; // Prüft auf Geleichheit
    
    		// Attribute //
    	private:
    		const EVENT_HANDLE m_handle;
    };
    // ...
    

    CEventHandle ist die ausgelagerte Uncopyable-Klasse.



  • Edit: Alles vorherige bitte vergessen.

    Du kannst Klassen, die keinen Zuweisungsoperator unterstützen, nicht immer mit der STL verwenden. std::fill() überschreibt Objekte, indem es den Zuweisungsoperator aufruft. Dafür scheint mir die Fehlermeldung aber etwas unangebracht zu sein...



  • Dann stellt sich mir aber die Frage, warum die Klasse CEevnt plötzlich kein Standard-Zuweisungsoperator mehr bekommt?



  • Weil sie ein const -Member hat.



  • Ahh^^ 💡 Stimmt, das habe ich auch geändert...

    Dann danke ich Euch für die rasant-schnelle Hilfe! 🙂

    Kompilierung läuft...
    EventGroup.cpp

    EventGroup.obj - 0 Fehler, 0 Warnung(en)

    👍



  • Keine Ursache. Ich würde bei solchen Fehlern immer darauf achten, was der Compiler nicht akzeptiert. Hier waren das die Funktionen std::fill() und std::copy_backward() . Dann vergleichst du die Anforderungen dieser Funktionen mit deiner Klasse und schaust, was nicht kompatibel ist.

    Die Anforderungen findest du zum Teil durch Überlegen heraus (z.B. fill() überschreibt eine bereits vorhandene Sequenz mit einem neuen Wert, also wird höchstwahrscheinlich ein Zuweisungsoperator benötigt). Oder du schaust auf www.cplusplus.com und siehst, dass der übergebene Iterator-Typ die Operatoren !=, * und ++ unterstützen muss, sowie für dein Objekt ein Operator = erforderlich ist. 🙂



  • Wobei ich einfach nicht darauf gekommen bin, dass eine Klasse mit const-Member kein Standard-Zuweisungsoperator bekommt.

    Dabei hatte ich die Klasse extra auf Kopierbarkeit etc. ausgelegt bzw. auslegen wollen.



  • Roger Wilco schrieb:

    Wobei ich einfach nicht darauf gekommen bin, dass eine Klasse mit const-Member kein Standard-Zuweisungsoperator bekommt.

    Jetzt weisst du es. 🙂

    Klar, manchmal sind Fehler nicht ganz einfach nachvollziehbar, besonders wenn man sie vorher noch nicht gemacht hat. Aber mit welcher Absicht hast du dann deinen Member const -qualifiziert? 😉



  • Das ist ein Event, welches diesem CEvent-Objekt bei der Objekt-Erzeugung fest zugeordnet wird. Daher const, damit ich versehentliches Ändern bemerke.

    #include <iostream>
    #include "Event.h"
    
    int main(){
    
       CEvent eventA;
       CEvent eventB;
    
       SetEventAfterFiveSeconds(eventA); // Macht nach 5 Sec. eventA.Set();
    
       eventB = eventA;
    
       eventB.Wait(); // nach 5 Sec...
       std::cout << "Ereignis B ist eingetreten!"; // Das sollte vermieden werden  
    }
    


  • Wenn du die Events zwar in einem Container speichern, aber nicht zuweisen willst, könntest du Boosts Pointer Container benutzen. Willst du den Kopierkonstruktor eigentlich nicht auch verbieten?



  • Nein, nein. Es war nur ein unüberlegt. Ich wollte etwas verhindern, was ich an anderer Stelle aber benötige.

    Wenn ich ein CEvent nicht verändert haben möchte, muss ich es eben als const CEvent deklarieren.


Anmelden zum Antworten