2

I'm sorry if this question has been asked before, I tried hard to find something like it, but I wasn't even sure what to search for.

Suppose I have following interface (this is just an example, my specific case have nothing to do with operators or addition) :

class AddAndSub
{
public:
  virtual AddAndSub operator +(AddAndSub const &) = 0;
  virtual AddAndSub operator -(AddAndSub const &) = 0;
}

Since a + b can be expressed as a - (-b) and a - b as a + (-b) (for simplicity let's assume negation is well defined for all deriving types) my first instinct was to simulate this property in the implementation, so only one of the operators need to be explicitly defined:

class AddAndSub
{
public:
  virtual AddAndSub operator +(AddAndSub const & b)
  {
    return *self - (-b);
  }
  virtual AddAndSub operator -(AddAndSub const & b)
  {
    return *self + (-b);
  }
}

However I'm not fully satisfied with my solution, since I'm still required to define at least one of the operations, but it's not explicitly enforced by the code and forgetting to define one results in very undescriptive error message "Stack overflow". I can leave the interface as it is in the first example to make sure every class implementing it defines required methods, but that in turns results in a lot of redundant code in non-tivial cases.

Is there a proper way to reduce code redundancy in situations like this while still keeping the compile time checks and leaving choice of which methods to implement to the interface user?

PS: I know I can just make one of those methods pure virtual but then I can't choose which method I can define in a case when it would be harder to implement addition than subtraction (which TBH is just a minor nitpick, but I'm still wondering if there is a better way).

Reverent Lapwing
  • 283
  • 2
  • 11
  • Side note: Designing plus operator that works in intuitive way for open class hierarchy is hard. Just preserving a+b=b+a is huge challenge. Convincing base class to correctly add some very derived class is interesting too.. – Alexei Levenkov Jan 01 '17 at 22:10
  • 1
    I would not use operators like this in a runtime polymorphism interface, aka. virtual operators. It will drastically limit the flexibility of your code. Consider using compile-time polymorphism and generic programming when dealing with arithmetic operators. – Guillaume Racicot Jan 01 '17 at 22:14

1 Answers1

1

It's better to keep your interface purely abstract. If you want to implement operator-() in terms of operator+() or vice versa, do that in your implementation class(es).

If for some reason you really want to minimize the number of methods your implementation class(es) have to override, consider creating a helper class that subclasses your interface and implements some methods in terms of others. You can mark those methods as final (a C++11 feature) to forbid them from being overridden again by your implementation class, which would be subclassing the helper one.

Joseph Artsimovich
  • 1,499
  • 10
  • 13
  • Helper classes seem like a solution to my problem, however I was hoping for something more like Haskell `Eq`, where it needs only `==` or `!=` to work. – Reverent Lapwing Jan 02 '17 at 07:35