C++ 重写多次继承的同一模板基类的公共方法 背景

C++ 重写多次继承的同一模板基类的公共方法 背景,c++,templates,multiple-inheritance,C++,Templates,Multiple Inheritance,我遇到了一个应用程序,在其中我可以使用一种方法: void AttachCallback(int event, std::functional<void(int)> cb); 但是,由于我最近经常使用模板,我想知道是否可以创建一个用于侦听给定事件的模板化纯虚拟类,并按如下方式使用它: template<const int EVENT> class ListensToEvent { public: virtual ~ListensToEvent() = defau

我遇到了一个应用程序,在其中我可以使用一种方法:

 void AttachCallback(int event, std::functional<void(int)> cb);
但是,由于我最近经常使用模板,我想知道是否可以创建一个用于侦听给定事件的模板化纯虚拟类,并按如下方式使用它:

template<const int EVENT>
class ListensToEvent {
 public:
  virtual ~ListensToEvent() = default;

 protected:
  ListensToEvent() {
    AttachCallback(EVENT, [this](int value) { cb(value); });
  }
  virtual void cb(int value) = 0;
};

class MyClass : public ListensToEvent<0>, public ListensToEvent<2> {
 private:
  void cb(int value) override;
};

template<>  // This line makes me suspicious
void MyClass::ListensToEvent<0>::cb(int value) {
  /*... callback for event 0 ...*/
}
template<>
void MyClass::ListensToEvent<2>::cb(int value) {
  /*... callback for event 2 ...*/
}
模板
类ListensToEvent{
公众:
virtual~ListensToEvent()=默认值;
受保护的:
ListensToEvent(){
AttachCallback(事件,[this](int值){cb(值);});
}
虚空cb(int值)=0;
};
类MyClass:public-ListensToEvent,public-ListensToEvent{
私人:
无效cb(int值)覆盖;
};
这句话让我怀疑
void MyClass::ListensToEvent::cb(int值){
/*…事件0的回调*/
}
模板
void MyClass::ListensToEvent::cb(int值){
/*…事件2的回调*/
}
在搜索相关主题时,我发现了一个示例,它显示了如何使用帮助器类来修复当两个基本接口提供相同标识符时发生的冲突。因为我在这里使用模板,所以我不能使用这样的帮助器,因为我不知道可以有多少个实例化,但是我发现,在没有专门化的情况下声明方法,然后在类定义之外提供模板专门化,这样我就可以分别针对每个基类的方法(如上所示)

概念证明 在进行测试时,我对这个设计进行了简化(没有回调),只是为了证明它能够编译和专门化

问题: 首先,我关心的是我对为什么这样做的理解。对我来说,通过使用
ListensToEvent
ListensToEvent
限定
cb
,可以指定在类定义之后实现的
cb
。我不明白的是,为什么资格认证被视为模板专业化,因此为什么需要行
template
。此外,如果这些条件实际上是模板特化,那么C++如何精确地看待方法的特殊性以及它们为什么工作?


话虽如此,我也对有关此设计功能的评论感兴趣。这是简化MyClass及其其他同级实现的一种有效方法,还是按照我提出的第一种方法做得更好?或者有没有其他设计在这种情况下工作得最好?

为什么要模板化整个类,而不仅仅是方法
cb
?我不喜欢,你说得对,听着。您将看到不需要在测试中调用。特别呼叫不需要是虚拟的。这就是为什么它是模板的特殊化。你说的“有效”的代码是不正确的。只要看看由clang生成的警告,您是否尝试执行类似的操作?@definecindyconst您可以专门化模板类的虚拟函数。编译器不允许您创建一个虚拟的模板成员函数!编译器报告的原始警告是,您调用
call
太早,此时用于分派的虚拟表未正确设置,无法将调用转发/分派到具体的类对象。这将给您带来您所期望的模糊性错误
template<const int EVENT>
class ListensToEvent {
 public:
  virtual ~ListensToEvent() = default;

 protected:
  ListensToEvent() {
    AttachCallback(EVENT, [this](int value) { cb(value); });
  }
  virtual void cb(int value) = 0;
};

class MyClass : public ListensToEvent<0>, public ListensToEvent<2> {
 private:
  void cb(int value) override;
};

template<>  // This line makes me suspicious
void MyClass::ListensToEvent<0>::cb(int value) {
  /*... callback for event 0 ...*/
}
template<>
void MyClass::ListensToEvent<2>::cb(int value) {
  /*... callback for event 2 ...*/
}