Ü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
..-Operatorwä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
..-Operatorwä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)statta..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.
-
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.
-
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