Вот довольно простой и довольно полный пример простого ADT для общего BoundedInt.
- В нем используются операторы boost /, чтобы избежать утомительных (постоянных, неназначающих) перегрузок.
- Неявные преобразования делают его совместимым.
- Я избегал интеллектуальных оптимизаций (поэтому код легче адаптировался, например, к версии по модулю или к версии, которая также имеет нижнюю границу)
- Я также избегал прямых шаблонных перегрузок для преобразования / работы со смешанными экземплярами (например, сравниваем BoundedInt с BoundedInt) по той же причине: вы, вероятно, можете полагаться на то, что компилятор оптимизирует его до того же эффекта в любом случае
Примечания:
- вам нужна поддержка c ++ 0x, чтобы значение по умолчанию для Max вступило в силу (поддержка constexpr ); Не требуется, если вы указали Макс вручную
Далее следует очень простая демонстрация.
#include <limits>
#include <iostream>
#include <boost/operators.hpp>
template <
typename Int=unsigned int,
Int Max=std::numeric_limits<Int>::max()>
struct BoundedInt : boost::operators<BoundedInt<Int, Max> >
{
BoundedInt(const Int& value) : _value(value) {}
Int get() const { return std::min(Max, _value); }
operator Int() const { return get(); }
friend std::ostream& operator<<(std::ostream& os, const BoundedInt& bi)
{ return std::cout << bi.get() << " [hidden: " << bi._value << "]"; }
bool operator<(const BoundedInt& x) const { return get()<x.get(); }
bool operator==(const BoundedInt& x) const { return get()==x.get(); }
BoundedInt& operator+=(const BoundedInt& x) { _value = get() + x.get(); return *this; }
BoundedInt& operator-=(const BoundedInt& x) { _value = get() - x.get(); return *this; }
BoundedInt& operator*=(const BoundedInt& x) { _value = get() * x.get(); return *this; }
BoundedInt& operator/=(const BoundedInt& x) { _value = get() / x.get(); return *this; }
BoundedInt& operator%=(const BoundedInt& x) { _value = get() % x.get(); return *this; }
BoundedInt& operator|=(const BoundedInt& x) { _value = get() | x.get(); return *this; }
BoundedInt& operator&=(const BoundedInt& x) { _value = get() & x.get(); return *this; }
BoundedInt& operator^=(const BoundedInt& x) { _value = get() ^ x.get(); return *this; }
BoundedInt& operator++() { _value = get()+1; return *this; }
BoundedInt& operator--() { _value = get()-1; return *this; }
private:
Int _value;
};
Пример использования:
typedef BoundedInt<unsigned int, 100> max100;
int main()
{
max100 i = 1;
std::cout << (i *= 10) << std::endl;
std::cout << (i *= 6 ) << std::endl;
std::cout << (i *= 2 ) << std::endl;
std::cout << (i -= 40) << std::endl;
std::cout << (i += 1 ) << std::endl;
}
Демонстрационный вывод:
10 [hidden: 10]
60 [hidden: 60]
100 [hidden: 120]
60 [hidden: 60]
61 [hidden: 61]
Бонусный материал:
С полностью совместимым с ++ 11 компилятором вы даже можете определить определяемое пользователем литералом преобразование:
typedef BoundedInt<unsigned int, 100> max100;
static max100 operator ""_b(unsigned int i)
{
return max100(unsigned int i);
}
Чтобы вы могли написать
max100 x = 123_b; // 100
int y = 2_b*60 - 30; // 70