我有一个基类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
对象上调用它,则会改为选择模板方法。
有没有办法在所有消息类中选择自定义函数,同时让模板捕获所有其他类型?
答案 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在我写作时提出的解决方案同时解决了这两个问题。