继承类中的比较运算符

c.b*_*ear 15 c++ c++11

我已经定义了一个IntWrapper类如下的类:

struct IntWrapper
{
protected:
  int value;

public:
  explicit IntWrapper() = default;
  explicit IntWrapper(const int value) : value(value) {}

  bool operator< (const IntWrapper rhs) const { return value <  rhs.value; }
  bool operator> (const IntWrapper rhs) const { return value >  rhs.value; }
  bool operator<=(const IntWrapper rhs) const { return value <= rhs.value; }
  bool operator>=(const IntWrapper rhs) const { return value >= rhs.value; }
  bool operator==(const IntWrapper rhs) const { return value == rhs.value; }

  explicit operator int() const { return value; }
};
Run Code Online (Sandbox Code Playgroud)

与类FooBar从继承IntWrapper

struct Foo: IntWrapper
{
  using IntWrapper::IntWrapper;
};

struct Bar: IntWrapper
{
  using IntWrapper::IntWrapper;
};
Run Code Online (Sandbox Code Playgroud)

我想只比较相同类型的对象.换句话说,我想下面这段给出编译错误,而不是铸造foobarIntWrapper.

const Foo foo(1);
const Bar bar(2);
bool b = foo >= bar;
Run Code Online (Sandbox Code Playgroud)

既然我有许多其他对象喜欢FooBar,有没有办法实现我的结果保持所有的比较运算符IntWrapper

YSC*_*YSC 9

您可以向您添加虚拟模板,IntWrapper以使比较运算符IntWrapper仅适用于同一类型:

template<class>
struct IntWrapper
{ /* same code */ };

struct Foo : IntWrapper<Foo> { using IntWrapper::IntWrapper; };
struct Bar : IntWrapper<Bar> { using IntWrapper::IntWrapper; };

int main()
{
    const Foo foo(1);
    const Bar bar(2);
    //bool b = foo >= bar; // error: no match for 'operator>=' (operand types are 'const Foo' and 'const Bar')
}
Run Code Online (Sandbox Code Playgroud)

现场演示

  • @liliscent请原谅?http://coliru.stacked-crooked.com/a/a075fb8c41c265da (2认同)
  • 如果你有2个不同的派生形式为'Foo`,他们*可以在你的代码中进行比较,这不是OP的预期结果.这里的问题是你需要跟踪最基类中派生最多的一个,完整的解决方案将使一切成为模板. (2认同)
  • 假设存在多个继承级别.我的理解是,这是一个泛型类型安全的int类型,意味着只要你需要一种新类型的safe int而继承,继承"tree"就会停止. (2认同)

ein*_*ica 5

我想只比较相同类型的对象.

如果你想要两个IntWrapper实例可以比较,但不是从IntWrapper继承的类的实例,你实际上说你并不真的希望这些类继承IntWrapper.

  • @YSC 建议您使用CRTP模式阻止此继承,以便每个类继承其"自己的"IntWrapper.这样可以防止代码重复.
  • 您可以更改比较运算符,以便检查两者都是IntWrapper的同一子类.
  • 您可以将可比性归因于IntWrapper的子类,Foo和Bar不会继承它.

并且可能有更多方法可以实现这一目标.但是,再次,这听起来像一个有问题的设计.