Vergleichsoperatoren überladen?



  • Hallo,
    arbeite zur Zeit an einem Projekt, das an einer Stelle einen Vergleich durchführt. Die Methode zum Vergleichen soll 6 verschiedene Vergleichsarten ausführen können. Aber ich weiß nicht so ganz, wie ich das anstellen soll, ohne den Vergleichs-Part zu kopieren (nur mit anderen Vergleichsoperator).
    Im Moment nutze ich 6 Vergleichs-Parts. Finde das aber redundant...

    Hier der Code auf Nötigste vereinfacht:

    void compare(int x, int y)
    {
        switch(mode)
        {
        case 0:
            if(x == y)
            {
                //...
            }
        break;
        case 1:
            if(x!= y)
            {
                //...
            }
        break; 
        case 2:
            if(x < y)
            {
                //...
            }
        break; 
    //usw
        }
    }
    

    Das ganze dient zum Vergleichen von Memory Dumps.
    Also wäre es praktisch, wenn ich immer die selbe Funktion aufrufen würde und den Operator irgendwie mit übergebe, überlade oder so.

    danke



  • Verstehe ich nicht. Statt

    void compare(int x, int y)
    {
    switch(mode)
    {
    case 0:
    if(x == y)
    {
    //...
    }
    break;

    hättest du dann

    void compare(int x, int y, OP op)
     {
         switch(mode)
         {
         case 0:
             if(op(x,y))
             {
                 //...
             }
         break;
    
    

    ?
    Oder wie ist da gemeint?

    Ist // ... immer dasselbe?



  • @manni66 sagte in Vergleichsoperatoren überladen?:

    Ist // ... immer dasselbe?

    Ja. Sorry, wenn ich es etwas unklar formuliert habe



  • Du kannst das Ergebnis des Vergleichs einer Variablen zuweisen.

    bool do_compare(int x, int y, int mode) {
        switch (mode) {
        case 0: return x == y;
        case 1: return x != y;
        ...
        }
        // Fehlerfall hier
    }
    
    bool comare = do_compare(x, y, mode);
    if (compare) {
      ...
    }
    
    

  • Mod

    Und ja, du kannst natürlich auch Operatoren an eine Funktion übergeben, schau mal hier unter "Operator function objects":
    https://en.cppreference.com/w/cpp/utility/functional

    Oder statt der Switches kannst die Dinger in eine map packen, die dir den Modus auf die Funktion abbildet.



  • @wob
    Das würde, glaube ich nicht so leicht funktionieren, da der Vergleich innerhalb einer for-Schleife liegt (Vergleicht anhand einer Pointer-Tabelle 2 Memory Dumps).
    Bin grade unterwegs und kann den Quellcode später hier posten, falls das hilft



  • @sucy_manbavaran sagte in Vergleichsoperatoren überladen?:

    Das würde, glaube ich nicht so leicht funktionieren, da der Vergleich innerhalb einer for-Schleife liegt

    Wo ist da der Zusammenhang?!



  • @sucy_manbavaran sagte in Vergleichsoperatoren überladen?:

    kann den Quellcode später hier posten, falls das hilft

    Für mich ist immer noch unklar, was genau du machen willst. Woher kommt mode?

    @wob sagte in Vergleichsoperatoren überladen?:

    @sucy_manbavaran sagte in Vergleichsoperatoren überladen?:

    Das würde, glaube ich nicht so leicht funktionieren, da der Vergleich innerhalb einer for-Schleife liegt

    Wo ist da der Zusammenhang?!

    Genau.



  • Okay, hier der ganze betreffende Teil:

    template<typename X, typename dType> void Search::compare(X oldMemDumpPTR, X newMemDumpPTR)
    {
        dType oldVal, newVal;
    
        switch(condition)
        {
        case 0:
            for(int i = 0; i < (offsetListSize/sizeof(long long)); i++)
            {
                oldVal = *(X)(oldMemDumpPTR + *(oldOffsetListPTR+i));
                newVal = *(X)(newMemDumpPTR + *(oldOffsetListPTR+i));
    
                if(newVal == oldVal)
                {
                    *(newOffsetListPTR+hits) = *(oldOffsetListPTR+i);
                    hits++;
                }
            }
            break;
        case 1:
            for(int i = 0; i < (offsetListSize/sizeof(long long)); i++)
            {
                oldVal = *(X)(oldMemDumpPTR + *(oldOffsetListPTR+i));
                newVal = *(X)(newMemDumpPTR + *(oldOffsetListPTR+i));
    
                if(newVal != oldVal)
                {
                    *(newOffsetListPTR+hits) = *(oldOffsetListPTR+i);
                    hits++;
                }
            }
            break;
        case 2:
            for(int i = 0; i < (offsetListSize/sizeof(long long)); i++)
            {
                oldVal = *(X)(oldMemDumpPTR + *(oldOffsetListPTR+i));
                newVal = *(X)(newMemDumpPTR + *(oldOffsetListPTR+i));
    
                if(newVal > oldVal)
                {
                    *(newOffsetListPTR+hits) = *(oldOffsetListPTR+i);
                    hits++;
                }
            }
            break;
        case 3:
            for(int i = 0; i < (offsetListSize/sizeof(long long)); i++)
            {
                oldVal = *(X)(oldMemDumpPTR + *(oldOffsetListPTR+i));
                newVal = *(X)(newMemDumpPTR + *(oldOffsetListPTR+i));
    
                if(newVal >= oldVal)
                {
                    *(newOffsetListPTR+hits) = *(oldOffsetListPTR+i);
                    hits++;
                }
            }
            break;
        case 4:
            for(int i = 0; i < (offsetListSize/sizeof(long long)); i++)
            {
                oldVal = *(X)(oldMemDumpPTR + *(oldOffsetListPTR+i));
                newVal = *(X)(newMemDumpPTR + *(oldOffsetListPTR+i));
    
                if(newVal < oldVal)
                {
                    *(newOffsetListPTR+hits) = *(oldOffsetListPTR+i);
                    hits++;
                }
            }
            break;
        case 5:
            for(int i = 0; i < (offsetListSize/sizeof(long long)); i++)
            {
                oldVal = *(X)(oldMemDumpPTR + *(oldOffsetListPTR+i));
                newVal = *(X)(newMemDumpPTR + *(oldOffsetListPTR+i));
    
                if(newVal <= oldVal)
                {
                    *(newOffsetListPTR+hits) = *(oldOffsetListPTR+i);
                    hits++;
                }
            }
            break;
    	default: break;
        }
    }
    
    

    Hoffe das ist jetzt etwas klarer.

    Da der Vergleich innerhalb einer for-Schleife abläuft, denke ich, kann ich @wob's Lösungsansatz hier nicht verwenden. Correct me if I'm wrong


  • Mod

    Es wird zwar immer geheimnisvoller, weil jetzt nicht nur condition, sondern auch noch mehr Information irgendwie magisch von außen kommt, aber es gilt nach wie vor, dass man problemlos die Operatoren wie ein funktionsartiges Objekt speichern und aufrufen kann.



  • Klar kannst du den Ansatz genauso verwenden. Nur wird dann innerhalb der Schleife jedesmal die Funktion do_compare aufgerufen (und dessen switch-Anweisung ausgeführt).

    Da sich der mode innerhalb der Schleife nicht ändert, kannst du einfach den von @SeppJ beschriebenen Ansatz benutzen:

    template<typename T>
    Func<bool, T, T> get_compare_op(int mode)
    {
        switch (mode)
        {
            case 0: return equal_to;
            case 1: return not_equal_to;
            // ...
        }
        
        throw logical_error("unknown mode");
    }
    

    // in deiner Funktion

    Func<bool, dType, dType> func = get_compare_op(mode);
    
    for(int i = 0; i < (offsetListSize/sizeof(long long)); i++)
    {
        oldVal = *(X)(oldMemDumpPTR + *(oldOffsetListPTR+i));
        newVal = *(X)(newMemDumpPTR + *(oldOffsetListPTR+i));
    
        if (func(newVal, oldVal))
        {
            *(newOffsetListPTR+hits) = *(oldOffsetListPTR+i);
            hits++;
        }
    }
    


  • Wahrscheinlich liegt es an mir aber ich kann mir grad' partout kein Dingsti einbilden für daß es irgendwie einen Sinn ergeben könnte es auf sechs verschiedene arten mit einem anderen Dinsti zu vergleichen.



  • @Swordfish Ich denke, das wird ein kleiner Helfer, um den Speicher in anderen Programmen (Spielen) zu modifizieren, wenn nicht ganz klar ist, welcher Wert genau im Speicher steht.
    Für die erste Suche wird ein Bereich angegeben, für jede weitere Suche dann nur, wie sich der Wert zum vorherigen verhält. Und so grenzt man es eben immer weiter ein.
    Funktioniert eigentlich ganz gut.



  • @yahendrik ah. ok. Compare sollte das dann aber eher nicht heißen.


Log in to reply