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



  • Hallo zusammen,

    ich suche nach einem Befehl, den ich aus Ruby kenne und jetzt gerne in C++ benutzen würde. Weiß' aber leider nicht wie das in C++ aussehen müsste 😞

    Vielleicht weiß jemand von euch die Lösung.

    In Ruby sieht das ganze so aus:

    # Check aller X-Koordianten
    x=0
    while x<=60  
    check="#{@x_monster+x}".to_i
    if (@x_osito..@x_osito+40).include? check 
      collision_monster_x=true
    end
    x+=1
    end
    

    Also bräuchte zum Einen einen Befehl um eine Spanne von Zahlen festzulegen wie
    "40..50".
    Und dann einen Befehl um zu überprüfen, ob eine andere Zahl sich in dieser Spanne befindet...
    in Ruby: 40..50.include? 42
    => true
    Und in C++? 😕
    Jemand eine Idee?



  • Sowas?

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


  • 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