2010-09-28 22 views
11

Mam problem, który jest dość powszechny w kodzie, który piszę w tym momencie, w którym chcę mieć liczbę całkowitą, która może istnieć tylko w pewnym zakresie, gdzie zakres wynosi [początek, koniec]. Zasadniczo chcę być w stanie zrobić coś takiego:Czy istnieje standardowa cykliczna klasa całkowita w C++?

cyclic_int ci(4, 8); 

ci = 4; 
assert(ci == 4); 
ci += 3; 
assert(ci == 7); 
ci += 2; 
assert(ci == 5); 
assert(ci == 13); 

I to wszystko powinno być prawdziwe. Zasadniczo klasa automatycznie stosuje modulus (%) dla mnie, a liczba całkowita działa jako cykliczna liczba całkowita w zakresie, w którym ją inicjuję. Mogłabym zaimplementować tę klasę samodzielnie i przeciążyć wszystkie popularne operatory, aby działała ładnie z normalnymi liczbami całkowitymi, ale wydaje się być użyteczną klasą, którą ktoś mógł zrobić wcześniej.

Moje pytanie brzmi: czy istnieje taka wspólna klasa, gdzieś, co wszyscy używają, czy też myślę, że robię to w niewłaściwy sposób i czy istnieje lepszy, prostszy sposób. (Moim celem jest, aby nie musieć ciągle myśleć o zastosowaniu operatora% lub jakiejkolwiek podobnej funkcji nad nim) Dzięki.

Edit: Postanowiłem napisać własny jedno, jak również dla zabawy: http://github.com/robertmassaioli/wrapping_number

+1

Jak daleko jak wiem, nie ma "standardu branżowego" dla tego typu rzeczy - jak biblioteka Boost, jeśli o to ci chodzi. Ale jak powiedziałeś, powinno być dość łatwo wprowadzić taką klasę i przeciążyć wszystkich niezbędnych operatorów. –

+1

Używanie komentarza zamiast odpowiedzi, ponieważ 1) Nigdy go nie użyłem i 2) Nie jest to jeszcze oficjalna biblioteka Boost, ale: Boost.ConstrainedValue ma "wrapping_int", która wygląda bardzo podobnie do tego, czego szukasz: http: //student.agh.edu.pl/~kawulak/constrained_value/constrained_value/tutorial.html#constrained_value.tutorial.other_error_policies_for_bounded_objects –

+0

@Eric: Dokładnie tego szukałem, ale nie jest jeszcze poza bibliotekami boost. Próbowałem się rozejrzeć i nie mogłem znaleźć implementacji referencyjnej. Będę szukał, ale czy wiesz gdzie jest? –

Odpowiedz

2

Nigdy go nie używałem i nie jest to jeszcze oficjalna biblioteka Boost, ale Boost.ConstrainedValue ma numer wrapping_int, który wygląda bardzo podobnie do tego, czego szukasz.

Chociaż nie jest jeszcze częścią Boost został przeglądowi i, IIUC, warunkowo przyjęty niedawno: http://lists.boost.org/boost-announce/2010/09/0265.php

Biblioteka jest dostępna na http://rk.dl.pl/f/constrained_value.zip

Dokumentacja jest w http://rk.dl.pl/r/constrained_value

+0

Napisałem także swój własny, również dla zabawy: http://github.com/robertmassaioli/wrapping_number –

4

nie jest ona łatwiejsza w użyciu funkcji normalize?

int normalize(int val, int start, int end) 
{ 
    return (val - start) % (end - start) + start; 
} 


int ci = 4; 
assert(ci == 4); 
ci = normalize(ci + 3, 4, 8); 
assert(ci == 7); 
ci = normalize(ci + 2, 4, 8); 
assert(ci == 5); 
assert(ci == 13); 
+1

Tego właśnie starałem się uniknąć, ponieważ nie chcę naprawdę myśleć o zastosowaniu funkcji normalizacji (ponieważ w końcu o tym zapomnę). A ostatni dowód też mi się nie uda? –

+0

Właściwie myślę, że ostatni argument powinien zawodzić, ponieważ 13 nie jest zdefiniowany jako liczba ograniczona przez zakres, użyłbym assert (ci == cyclic_int <4,8> (13)); (szablon jest wygodny tutaj) – stefaanv

+0

@stefaanv: Myślę, że to co on robi to to, że 13 powinno być przystające do 5 w cyklicznym (4, 8) (to znaczy zawiera liczby całkowite 4, 5, ...12), którym jest. Zgadzam się z pojęciem szablonu ... zapewnia silniejsze pisanie. – andand

Powiązane problemy