C++:重写从模板类派生的虚拟纯函数
我写了一些基于此优秀访问者模式描述的类here(我的实现有点不同)。C++:重写从模板类派生的虚拟纯函数
template<typename... Types>
class Visitable {
public:
virtual void accept(Visitor<Types...>& visitor) = 0;
};
class MyClass : public Visitable<int, string>
{
virtual void accept(Visitor<int, string>& visitor)
{
/*** my code ***/
}
};
这上面的代码工作,但我想实现MyClass
这样的:
class MyClass : public Visitable<int, string>
{
template<typename... Types>
virtual void accept(Visitor<Types...>& visitor)
{
/*** my code ***/
}
};
显然我改变了调用accept方法,但我有此错误:“不能实例化抽象类” 。为什么在第二种情况下,accept()
未被覆盖? MyClass应该模板化?
谢谢。
使用CRTP:
template<class D, class...Ts>
struct Visitable_CRTP : public Visitable<Ts...> {
virtual void accept(Visitor<Ts...>& visitor) override final {
return static_cast<D*>(this)->accept_impl(visitor);
}
};
class MyClass : public Visitable_CRTP<MyClass, int, string>
{
template<typename... Types>
void accept_impl(Visitor<Types...>& visitor) // not virtual
{
/*** my code ***/
}
};
Visitor_CRTP
写道,重视virtual accept
您template accept_impl
胶水代码。
如果你想有一个以上的accept
方法,我们可以这样做:
template<class D, class...Visitables>
struct PolyVisitable_CRTP {};
template<class D, class...V0, class...Vs>
struct PolyVisitable_CRTP<D, Visitable<V0...>, Vs...>
Visitable_CRTP<D, V0...>,
PolyVisitable_CRTP<D, Vs...>
{};
它可以这样使用:
class MyClass :
public PolyVisitable_CRTP<MyClass,
Visitable<int,double>,
Visitable<std::string, char, wchar_t>,
Visitable<>
>
{
template<typename... Types>
void accept_impl(Visitor<Types...>& visitor)
{
/*** my code ***/
}
};
和所有Visitable
基地的accept
S的意志被路由到accept_impl
。
未经测试或编译的代码,可能包含tpyos。
至少“tpyos”一词包含一个错字:) –
非常感谢你这个优秀的答案! – Milleras
事实上,你尝试实施
void VisitTable<int, string>::accept(Visitor<int, string>& visitor);
与
void MyClass::accept<int, string>(Visitor<int, string>& visitor);
在C++中,它是不一样的方法名字 - 一个带一个模版资格,其他没有。此外template
和virtual
是不兼容的方法说明符和你应该有
class MyClass : ... {
...
template<typename... Types>
virtual void accept(Visitor<Types...>& visitor);
};
error: templates may not be ‘virtual’
错误的override
C++ 11的关键字有助于避免这样的惊喜。
你的评论我现在明白我的错误。谢谢。通常我使用'override',但在这里我忘了它。 – Milleras
模板不是函数,所以没有函数来覆盖基类函数。 –