【问题标题】:"multiple overloads" using templated class with duplicate types“多重重载”使用具有重复类型的模板类
【发布时间】:2018-09-22 16:36:13
【问题描述】:

我正在尝试编写一个采用两种模板类型的类。这个类继承自一个接口。请参阅下面的代码。

#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 函数

谢谢!

【问题讨论】:

  • 这不仅仅是多重重载(你可以用一些enable_if 魔法修复),而且你还从同一个基类派生了两次,这也是不允许的。 @VTT 的回答解决了这两个问题。

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


【解决方案1】:

专业化怎么样:

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

【讨论】:

    【解决方案2】:

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

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

    另一种可能性是将Ts 之一放入另一个容器中。我在这个例子中使用了 Shell 结构:

    模板 结构壳{ 吨; 壳牌(T t):t(t){} 运算符 T() const {返回 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));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多