mbtg
mbtg

Reputation: 95

Inherit operators defined outside class

In this minimal example I have a class A with an operator + defined outsise of it:

template<class T> class A {};

template<class T1, class T2> void operator+(A<T1> a, A<T2> b) {}

template<class T> class B : public A<T> {};

int main(int, char**) {
    B<int> a, b;
    a + b;
    return 0;
}

I've tried to create an implicit conversion from B to A but it requires the operator+ to be a friend of A and be defined inside A which will cause problems when more than one instance of A<...> gets instantiated.

So, is there any other way to do this without having to define the operator+ again?

Thank you in advance for any help.

Upvotes: 0

Views: 55

Answers (1)

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275800

template<class T> class A {
  template<class T2>
  friend void operator+(A const& lhs, A<T2> const& rhs) {}
};

template<class T> class B : public A<T> {};

int main(int, char**) {
  B<int> a, b;
  a + b;
  return 0;
}

this works. The assymetry in + (one template, one not) ensure that multiple As don't conflict with their +.

In some situations you really need lhs to be an instance of B:

template<class T> struct A {
  template<class D, class T2, std::enable_if_t<std::is_base_of<A, D>{}, bool> =true >
  friend void operator+(D const& lhs, A<T2> const& rhs) {
    std::cout << D::name() << "\n";
  }
  static std::string name() { return "A"; }
};

template<class T> struct B : public A<T> {
  static std::string name() { return "B"; }
};

int main(int, char**) {
  B<int> a, b;
  a + b;
  return 0;
}

which uses A's operator+, but the LHS is of type B. Doing this for B<T2> on the right hand side isn't very viable, it gets ridiculous.

Upvotes: 1

Related Questions