«множественные перегрузки» с использованием шаблонного класса с дублирующимися типами - PullRequest
0 голосов
/ 22 сентября 2018

Я пытаюсь написать класс, который принимает два шаблонных типа.Этот класс наследуется от интерфейса.См. Приведенный ниже код.

#include <iostream>
#include <string>

template <typename T>
class IObserver {
 public:
  virtual void Next(const T& value) noexcept = 0;
};

template <typename T1, typename T2>
class BinaryObserver : public IObserver<T1>, public IObserver<T2> {
 public:
  void Next(const T1& value) noexcept override{};

  void Next(const T2& value) noexcept override{};
};

int main() {
  // This is OK
  BinaryObserver<int, float> mc1;
  mc1.Next(0);
  mc1.Next(0.0f);

  // This fails to compile with "multiple overloads"
  BinaryObserver<int, int> mc2;
  mc2.Next(0);
  mc2.Next(0);
}

У меня проблемы, когда T1 того же типа, что и T2.Очевидно, это означает, что будут сгенерированы две функции Next с одним и тем же типом, что приводит к ошибке: multiple overloads of 'Next' instantiate to the same signature.

Какой идиоматический способ исправить это?Я не уверен, как справиться со случаем, когда T1 = T2, так как мне нужна только одна сгенерированная Next функция

Спасибо!

Ответы [ 2 ]

0 голосов
/ 22 сентября 2018

У вас есть другая проблема в вашей программе:

BinaryObserver<int, int> mc2;
mc2.Next(0);
mc2.Next(0);

Какую из Next вы ожидаете, что компилятор выберет в случае успеха?В ответе VIT у вас будет только один Next, реализованный в спецификации, и его двойной вызов вызовет что-то другое.

Итак, лучшее решение - иметь разные классы IObserver с разными именами функций для перегрузки., т.е.

class BinaryObserver : public IObserver<T1>, public IObserver1<T2> 
...
mc2.Next(0);
mc2.Next1(0);    

Другая возможность состоит в том, чтобы поместить один из T s в другой контейнер.В этом примере я использовал структуру Shell:

шаблон структуры Shell {T t;Оболочка (T t): t (t) {} оператор T () const {return t;}};

template <typename T1, typename T2>
class BinaryObserver : public IObserver<T1>, public IObserver<Shell<T2>> {
 public:
  void Next(const T1& value) noexcept override{T1 t = value;};
  void Next(const Shell<T2>& value) noexcept override{T2 t = value;};
};

...

  BinaryObserver<int, float> mc1;
  mc1.Next(0);
  mc1.Next(0.0f);

  BinaryObserver<int, int> mc2;
  mc2.Next(0);
  mc2.Next(Shell<int>(0));
0 голосов
/ 22 сентября 2018

Как насчет специализации:

template <typename T>
class BinaryObserver<T, T> : public IObserver<T> {
 public:
  void Next(const T & value) noexcept override{};
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...