Наследовать операторы, определенные вне класса - PullRequest
0 голосов
/ 07 мая 2018

В этом минимальном примере у меня есть класс A с оператором +, определенным вне его:

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;
}

Я пытался создать неявное преобразование из B в A но для этого требуется, чтобы operator+ было friend из A и было определено внутри A, что вызовет проблемы при создании более одного экземпляра A<...>.

Итак, этоЕсть ли другой способ сделать это без необходимости заново определять operator+?

Заранее спасибо за любую помощь.

1 Ответ

0 голосов
/ 07 мая 2018
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;
}

это работает. Ассиметрия в + (один шаблон, один - нет) гарантирует, что несколько A не конфликтуют с их +.

В некоторых ситуациях вам действительно нужно, чтобы lhs был экземпляром 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;
}

, который использует A operator+, но LHS имеет тип B. Делать это для B<T2> на правой стороне не очень жизнеспособно, это становится смешным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...