Überprüfen, ob ein Zahlwert in einer Spanne von Werten enthalten ist



  • Ich glaube ich reiche ein Proposal ein für einen neuen Operator. Ein ..-Operator wäre, was solche Ranges anbelangt wirklich intuitiv. 🙂 (Eiffel hat den auch)



  • Nexus schrieb:

    Sowas?

    bool is_inside(int lower, int upper, int value)
    {
        return lower <= value && value <= upper;
    }
    

    Also muss ich dafür eine Extra-Funktion schreiben, richtig?
    Dachte es gäbe vielleicht auch sowas wie den ".."-Operator und include?
    in C++.

    Danke jedenfalls für die Antworten! 🙂



  • drakon schrieb:

    Ich glaube ich reiche ein Proposal ein für einen neuen Operator. Ein ..-Operator wäre, was solche Ranges anbelangt wirklich intuitiv. 🙂 (Eiffel hat den auch)

    Haskell hat den auch, ist wirklich praktisch... So kann man zum Beispiel alle geraden Zahlen zwischen 1 und 9 auflisten: 🙂

    filter (\n -> mod n 2 == 0) [1..9]
    

    In C++ braucht man das wohl definitiv zu selten. Aber man kann sich ja eine Ganzzahl-Intervall-Klasse schreiben und alle möglichen Mengenoperationen überladen. Ist dann halt Interval(a, b) statt a..b , aber dafür geht es mit momentanen Mitteln.

    Barcelona schrieb:

    Also muss ich dafür eine Extra-Funktion schreiben, richtig?
    Dachte es gäbe vielleicht auch sowas wie den ".."-Operator und include?
    in C++.

    Nein, C++ verfolgt andere Ansätze als Ruby. Aber du kannst dir die Funktionalität wie gesagt leicht mittels Klassen nachbilden, die Syntax kannst du jedoch nicht 1:1 übernehmen (solltest du im Übrigen auch nicht versuchen).



  • Nexus schrieb:

    die Syntax kannst du jedoch nicht 1:1 übernehmen

    Aber mit ein bisschen Gefrickel fast:

    struct range
    {
        int lower, upper;
    };
    
    range operator +(int i, range r)
    {
        r.lower = i;
        return r;
    }
    
    range operator +(range r, int i)
    {
        r.upper = i;
        return r;
    }
    
    #define TO + range() +
    

    Dann wäre der Operator nicht .. sonder TO. Wenn man noch entsprechende Member-Funktionen schreibt, kann man dann auch sowas machen wie if((1 TO 100).includes(42)) {...}

    Möchte man das unbedingt auch noch anders haben, geht das natürlich auch:

    bool operator &(const range& r, int i) // jeder andere von der Priorität passende Operator ginge auch
    {
        return i >= r.lower && i <= r.upper;
    }
    
    #define INCLUDES &
    

    Aufruf: if(1 TO 100 INCLUDES 42) {...}

    Aber natürlich sollte sowas in der Praxis nicht verwendet werden (wird auch nicht gemacht).



  • XMaster schrieb:

    Aufruf: if(1 TO 100 INCLUDES 42) {...}

    wobei zur not eine c++-ähnlichere syntax
    if(make_range(1,100).includes(42))
    auch denkbar wäre.



  • Man könnte jetzt natürlich noch ein wenig mehr mit Makros arbeiten und dann hätten wir auch schon die schönen Punkte.


  • Mod

    So ist es leider ziemlich lahm, ich hätte lieber Operator -> genutzt. Aber das bringt nichts, weil man den Elementzugriffsoperator . nicht überladen darf. Und Operator=> gibt's leider nicht. Darum 'nur' mit Kommaoperator. Namensraumauflösung :: wäre auch noch passend gewesen, aber das darf man auch nicht überladen. Verdammt, warum sind die ganzen cool aussehenden Operatoren verboten 😡 ?

    template<typename T> class rangecheck
    {
    private:
     T value;
    public:
     class range
     {
      private:
       T lower,upper;
       range(T l, T u):lower(l), upper(u){}
      public:
       bool includes(T t)
       {
        return lower <= t && t <= upper;
       }
       friend class rangecheck<T>;
     };
     range operator,(rangecheck<T> upper)
     {
      return range(value,upper.value);
     }
     rangecheck(T t):value(t){}
    };
    
    int main(){
     typedef rangecheck<int> integer;
     integer a=5;
     integer b=10;
     std::cout << (a,b).includes(8) << std::endl << (a,b).includes(11) << std::endl;
    }
    


  • Wieso sollte man den Elementzugrifssoperator -> nicht überladen dürfen? Sämtliche Iteratoren machen nichts anderes.


  • Mod

    DocShoe schrieb:

    Wieso sollte man den Elementzugrifssoperator -> nicht überladen dürfen? Sämtliche Iteratoren machen nichts anderes.

    Lies nochmal genau: Man darf ihn überladen, es bringt aber nichts für diesen Fall, weil man den Memberzugriffsoperator . nicht überladen darf. Daher kann man die linke Seite von -> nicht mit der rechten Seite von -> in Verbindung bringen, denn -> an sich hat nur die linke seite als Argument.



  • Narf o.O


Anmelden zum Antworten