我正在尝试编写一个具有两种模板化类型的类。此类从接口继承。请参见下面的代码。
#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
函数
谢谢!
答案 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));