remove_if: Alle Elemente löschen die != elem.GetSth() sind?



  • Funktioniert leider noch nicht ganz - kann mir aber nicht erklären warum. Hier mein Code (Nicht über die Konstanten und komische Typen wundern, das läuft hier so 🙄 (Trotzdem verständlich denke ich)):

    // Pred:
    template <class T>
    struct not_equal_to_member
    {
    	// Typen
    	typedef T (TRMode::*MethodPointer) () const;
    
    	// Aufzurufende Vergleichsmethode
    	PRIVATE MethodPointer mMethod;
    	// Vergleichswert
    	PRIVATE T mValue;
    
    	// Konstruktoren
    	PUBLIC not_equal_to_member (MethodPointer method, T value)
    		:
    	mMethod(method),
    	mValue(value)
    	{
    	}
    
    	// Operatoren
    	PUBLIC bool operator() (T elem) const
    	{
    		return mValue != (elem.*mMethod)();
    	}
    };
    
    // Aufruf (TRModeList : public std::list)
    // viel switch jeweils mit anderer methode
    eraseFrom = std::remove_if(begin(),end(),not_equal_to_member<int32>(&TRMode::GetHeight,value));
    
    erase(eraseFrom,end());
    

    Zuerst hab ich geglaubt, die Methoden dürfen ganz einfach nicht inline sein, aber das scheint auch nicht der Fall zu sein. Der MSVC liefert mir folgenden Compiler-Fehler für jeden Aufruf von remove_if:

    'not_equal_to_member<TEXT>::__ctor': Durch keine der 2 Überladungen kann Parameter 1 vom Typ 'int32 (__thiscall TRMode::* )(void) const' konvertiert werden
            with
            [
                TEXT=int32
            ]
            and
            [
                TEXT=int32
            ]
    
    kann 'not_equal_to_member<TEXT>::not_equal_to_member(not_equal_to_member<TEXT>::MethodPointer (__cdecl *),TEXT)' sein
            with
            [
                TEXT=int32
            ]
            bei Anpassung der Argumentliste '(int32 (__thiscall TRMode::* )(void) const, int32)'
    

    Was mach ich falsch?

    MfG SideWinder



  • Poste doch bitte noch die Definition von TRMode

    Gruß
    Werner



  • Hier:

    class TRMode
    {
    	PUBLIC_FOR_ENUMERATOR; // nicht mehr als ne friend-dekl, der darf TRMode als einziges erstellen
    
    	PRIVATE int32 mHeight;
          PRIVATE int32 mWidth; // und noch viel mehr nach dem muster, aber für die hier funktionierts schon nicht.
    
    	// Konstruktoren
    	INTERN TRMode () {}; // INTERN = private:
    
    	// Methoden - Getter
          PUBLIC INLINE int32 GetHeight () const { return mHeight; }
          PUBLIC INLINE int32 GetWidth () const { return mWidth; } // dito, noch ein paar nach dem muster
    };
    

    MfG SideWinder



  • Weils mir gerade auffällt: Kann das irgendwie mit den Aufrufkonventionen zusammenhängen? Einmal schreibt er was von __thiscall und einaml von __cdecl, vielleicht hauts deswegen nicht hin mit einem ordentlichen Pointer auf eine Methode?

    MfG SideWinder



  • Der Fehler ist der operator() (T elem)
    T wird durch int ersetzt, Du willst aber TRMode haben.

    Mach doch:

    template <class T, class X>
    struct not_equal_to_member
    {
        // Typen
        typedef T (X::*MethodPointer) () const;
    
        // Aufzurufende Vergleichsmethode
        private:
          MethodPointer mMethod;
        // Vergleichswert
           T mValue;
    
        // Konstruktoren
        public:
        not_equal_to_member (MethodPointer method, T value)
            :
        mMethod(method),
        mValue(value)
        {
        }
    
        // Operatoren
        bool operator() (X elem) const  // hier darf nicht T stehen
        {
            return mValue != (elem.*mMethod)();
        }
    };
    

    Damit kannst Du das Prädikat dann auch für andere Typen als TRMode einsetzen.



  • Hast recht, wäre aber offenbar nur ein Folgefehler gewesen. Er meckert ja beim Konstrukturaufruf und der hat mit dem op() noch nichts zu tun. Es funktioniert trotz der Richtigstellung immer noch nicht 😞

    /Edit: Hab hier mal einstweilen Boost installiert, mit Boost ists kein Problem. Bloß verstehe ich die Implementierung von denen nicht und direkt einsetzen kann ichs auhc nicht.

    MfG SideWinder



  • Folgender kleiner Test compiliert hier und liefert ein korrektes Ergebnis:

    #include <iostream>
    #include <vector>
    using namespace std;
    
    class Elem
    {
        int member;
    
        public:
            Elem( int y) : member( y) {};
            int GetMember () const { return member; }
    };
    
    template <class T, class X>
    struct not_equal_to_member
    {
        // Typen
        typedef T (X::*MethodPointer) () const;
    
        // Aufzurufende Vergleichsmethode
        private:
          MethodPointer mMethod;
        // Vergleichswert
           T mValue;
    
        // Konstruktoren
        public:
        not_equal_to_member (MethodPointer method, T value)
            :
        mMethod(method),
        mValue(value)
        {
        }
    
        // Operatoren
        bool operator() (X elem) const
        {
            return mValue != (elem.*mMethod)();
        }
    };
    
    int main()
    {
       vector<Elem> x;
       x.push_back( Elem( 1));
       x.push_back( Elem( 0));
       x.push_back( Elem( 2));
       x.push_back( Elem( 0));
       x.push_back( Elem( 3));
       for( int i = 0; i < 10; ++i) { x.push_back( Elem( i)); }
    
       int value = 0;
    
       vector<Elem>::iterator eraseFrom = 
         std::remove_if(x.begin(),x.end(),
                        not_equal_to_member<int, Elem>(&Elem::GetMember,value));
    
       x.erase(eraseFrom,x.end());
    
       for( vector<Elem>::const_iterator it = x.begin(); it != x.end(); ++it) {
       	cout << it->GetMember() << " ";
       }
       cout << endl;
    }
    

    Compiler ist irgendeine neuere GCC Version für Windows.



  • Nachtrag: Mit MSVC 7.1 geht's auch.



  • VERDAMMT VERDAMMT VERDAMMT VERDAMMT VERDAMMT VERDAMMT ICH SCHIESS SIE ALLE AB 😡

    Weil den Kerlen das TEXT()-Macro für hardcoded Unicode-Externalisierungen zu lang war haben die:

    #define T TEXT
    

    eingeführt. Ich mein wie kann man den Standard-Template-Parametr fast aller Template-Klassen im Umlauf nur umdefinieren? Ich sitz verdammte 11 Stunden vor dem PC und jetzt erst wundert mich in der Template-Fehlermeldung dieses TEXT als Paramter, das wird doch sonst nie gemacht. Und dann bimmelts, ich will heulen 😞

    MfG SideWinder



  • hey sidewinder warum wird denn in deiner firma makros für public und private benutzt? oder steckt da mehr hinter als

    #define PRIVATE private
    #define PUBLIC public

    😕



  • Keine Ahnung, sowas kann ich in meiner Stellung nicht hinterfragen. In 3 Wochen heißts für mich wieder ab in die Schule und die bekommen die Sourcen soweit ich gekommen bin.

    MfG SideWinder



  • lol man muss doch immer genau wissen was man tut und warum man etwas tut. 🤡



  • vielleicht alte java-hasen die mit C-makros C++ spielen wollen *hüstel*



  • Ist doch super praktisch wenn sich die keywords mal im Namen ändern.


Anmelden zum Antworten