继承类

时间:2018-05-11 13:09:04

标签: 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; }
};

以及继承自Foo

的班级BarIntWrapper
struct Foo: IntWrapper
{
  using IntWrapper::IntWrapper;
};

struct Bar: IntWrapper
{
  using IntWrapper::IntWrapper;
};

我想只比较相同类型的对象。换句话说,我希望以下部分给出编译错误,而不是将foobar投射到IntWrapper

const Foo foo(1);
const Bar bar(2);
bool b = foo >= bar;

由于我有许多其他对象,例如FooBar,有没有办法实现我的结果,将所有比较运算符保留在IntWrapper内?

3 个答案:

答案 0 :(得分: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')
}

live demo

答案 1 :(得分:5)

  

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

如果您希望两个IntWrapper实例可以比较,但不是从IntWrapper继承的类的实例,那么您实际上并不是说您不希望这些类继承自IntWrapper。

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

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

答案 2 :(得分:3)

为这些运算符使用模板并将其声明为朋友。

template <typename T, 
          std::enable_if_t<std::is_base_of_v<IntWrapper, T>, int> = 0> 
friend bool operator< (T lhs, T rhs) { return lhs.value <  rhs.value; }

现在,如果真实类型的参数不同,则T无法正确推断。

注意我不使用const T,因为top-level const of function parameter is ignored