[英]C++: Overriding virtual pure function derived from a template class
I wrote some classes based on this excellent visitor pattern described here (my implementation is a little bit different). 我根据此处描述的出色访客模式编写了一些类(我的实现有些不同)。
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 ***/
}
};
This code above works but I would like implement MyClass
like that: 上面的代码可以工作,但是我
MyClass
这样实现MyClass
:
class MyClass : public Visitable<int, string>
{
template<typename... Types>
virtual void accept(Visitor<Types...>& visitor)
{
/*** my code ***/
}
};
Obviously I changed the call to the accept method but I have this error: " cannot instantiate abstract class ". 显然,我将调用更改为accept方法,但是出现了以下错误:“ 无法实例化抽象类 ”。 Why in this second case,
accept()
is not overridden ? 为什么在第二种情况下,
accept()
不被覆盖? MyClass should be templated ? MyClass应该模板化吗?
Thanks. 谢谢。
Use the CRTP: 使用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
writes the glue code that attaches virtual accept
to your template accept_impl
. Visitor_CRTP
编写将virtual accept
附加到template accept_impl
的粘合代码。
If you want to have more than one accept
method, we can do this: 如果您想使用多个
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...>
{};
which can be used like this: 可以这样使用:
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 ***/
}
};
and all of the Visitable
bases's accept
s will be routed to accept_impl
. 并且所有
Visitable
bases的accept
都将路由到accept_impl
。
Code not tested or compiled, probably contains tpyos. 未经测试或编译的代码,可能包含tpyos。
In fact you try to implement 实际上,您尝试实施
void VisitTable<int, string>::accept(Visitor<int, string>& visitor);
with 同
void MyClass::accept<int, string>(Visitor<int, string>& visitor);
In C++ it is not the same method name - one has a template qualification and the other not. 在C ++中,方法名称不同-一个具有模板资格,另一个没有。 Moreover
template
and virtual
are incompatible specifiers for methods and you should have an error for 而且
template
和virtual
是方法的不兼容说明符,您应该为
class MyClass : ... {
...
template<typename... Types>
virtual void accept(Visitor<Types...>& visitor);
};
error: templates may not be ‘virtual’
The override
C++11 keyword helps to avoid such surprises. override
C ++ 11关键字有助于避免此类意外情况。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.