使用具有重复类型的模板化类的“多重重载”

时间:2018-09-22 16:36:14

标签: c++ c++11 templates overloading

我正在尝试编写一个具有两种模板化类型的类。此类从接口继承。请参见下面的代码。

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

T1T2属于同一类型时,我遇到了麻烦。显然,这意味着将生成两个具有相同类型的Next函数,这将产生错误:multiple overloads of 'Next' instantiate to the same signature

解决此问题的惯用方式是什么?我不确定在T1 = T2时该如何处理,因为我只需要生成一个Next函数

谢谢!

2 个答案:

答案 0 :(得分:14)

专业化如何?

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

答案 1 :(得分:0)

您的程序中还有另一个问题:

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中的一个放入另一个容器。在此示例中,我使用了Shell结构:

模板     struct Shell {       吨       Shell(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));