C ++:“专门化”一个成员函数模板,用于处理来自某个基类的派生类

时间:2014-02-02 10:36:25

标签: c++ templates overload-resolution

我有一个基类MessageBase,我从中导出了各种其他消息类,例如MessageDerived。我有另一个类对各种类型的数据进行处理,包括一个catchall方法模板:

struct Process {
  void f(int a);
  void f(const char* b);
  template<typename T> void f(const T &t) { ... }
};

因此,如果我在消息对象上调用Process::f,则会调用模板方法。

现在我想为我的消息类添加自定义功能。我不允许更改Process,因此我想从中获取(但即使我可以更改它,我也找不到获取自定义功能的方法)。我试过了:

struct ProcessDerived : public Process {
  void f(const MesaageBase& m) { ... }  // Custom functionality for messages.
};

但只有当我在ProcessDerived::f对象上调用MessageBase时,这才有效。如果我在MessageDerived对象上调用它,则会改为选择模板方法。

有没有办法在所有消息类中选择自定义函数,同时让模板捕获所有其他类型?

2 个答案:

答案 0 :(得分:2)

您需要在此处使用SFINAE。这是一个例子(注意它需要c ++ 11才能工作):

struct ProcessDerived : public Process
{
  template<typename T> void f(const T &t, typename std::conditional<std::is_base_of<MessageBase, T>::value, int, void>::type = 0)
  {
    /// do something specific
  }

  template<typename T> void f(const T &t, ...)
  {
    return Process::f (t);
  }
};

};

您可以在http://en.wikipedia.org/wiki/Substitution_failure_is_not_an_error

了解更多相关信息

答案 1 :(得分:0)

ProcessDerived :: f隐藏Process :: f的所有定义(参见此处:Overloading rules for inheritance in C++)。因此,使用MessageDerived对象调用ProcessDerived :: f会调用ProcessDerived :: f(const MessageBase&amp;),因为这是唯一可见的f,但是例如

ProcessDerived pd; 
pd(42);

不会编译。你需要添加一个

using Process::f;
在ProcessDerived中

显示您所描述的问题。然而,Alex Telishev在我写作时提出的解决方案同时解决了这两个问题。