2011-09-30 41 views

回答

6

下面是一个简单的ADT为通用BoundedInt的一个非常简单的和比较完整的例子。

  • 它使用boost/operators来避免编写繁琐的(常量,非赋值)重载。
  • 隐式转换使其可以互操作。
  • 我避之唯恐不及的智能优化(因此代码停留更容易适应,例如模版本,或者说有一个版本的下限为好)
  • 我也避之唯恐不及的直接模板重载转换/对混合实例操作(例如,比较一个BoundedInt到BoundedInt)出于同样的原因:你也许可以依靠编译器优化它的同样的效果呢

注:

  • 你需要的C++ 0x来支持允许Max的默认值生效(constexpr support); 您指定的最大不需要作为长手动

一个非常简单的演示如下。

#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] 

奖金材料:

有了一个完全的C++ 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 
+1

对于比我的更完整的演示+1。 – Bill

+0

完成后,除非确实需要对中间操作进行严格控制,否则实际上不需要重载每个操作员。我的课更简单,而且做同样的事情。 –

+0

@MarkRansom:我很难分辨究竟需要什么。我讨厌引入漏洞抽象 - 即使对于愚蠢的示例代码,IMO也应该持有[最低惊奇原则](http://c2.com/cgi/wiki?PrincipleOfLeastAstonishment)。我打算展示一个_generic_有界整数类,就像你可以很容易地从它作为模板声明的方式看到的一样。考虑这个_mould_。我将来可以参考这篇文章 – sehe

11

试试这个:

std::min(50 + 40, 100); 
std::min(50 + 50, 100); 
std::min(50 + 60, 100); 
std::min(50 + 90, 100); 

http://www.cplusplus.com/reference/algorithm/min/

另一种办法是每次操作后,使用此:

if (answer > 100) answer = 100; 
+1

或者如果你不想使用STL,你可以定义你自己的min函数,比如'template const T&min(const T&a,const T&b){return!(b jli

+7

为什么你不想使用标准库? –

0

您可以编写包含超载operator+operator-等运算符重载的例子自己的类IntegerRange,看到复杂的类here

0

最简单的方法是创建一个保存该值的类,而不是使用整型变量。

class LimitedInt 
{ 
    int value; 
public: 
    LimitedInt() : value(0) {} 
    LimitedInt(int i) : value(i) { if (value > 100) value = 100; } 
    operator int() const { return value; } 
    LimitedInt & operator=(int i) { value = i; if (value > 100) value = 100; return *this; } 
}; 

您可能会遇到麻烦,结果不符合预期。结果应该是70或90?

LimitedInt q = 2*60 - 30; 
0

Yes.

作为最低限度,你可以用this开始:

template <int T> 
class BoundedInt 
{ 
public: 
    explicit BoundedInt(int startValue = 0) : m_value(startValue) {} 
    operator int() { return m_value; } 

    BoundedInt operator+(int rhs) 
    { return BoundedInt(std::min((int)BoundedInt(m_value + rhs), T)); } 

private: 
    int m_value; 
}; 
0

C++不允许覆盖(重定义)基本类型的运算符。

如果自定义整数类(如上面建议的)不属于你的“简单方法”的定义,那么你的问题的答案是没有,没有简单的方法来做你想做的。

0

我知道这是一个旧帖子,但我认为它可能对某些人仍然有用。我用这个来设定上限和下限:

bounded_value = max(min(your_value,upper_bound),lower_bound); 

你可以在这样的函数中使用它:

float bounded_value(float x, float upper, float under){ 
    return max(min(x,upper),lower); 
} 
相关问题