我根据这个优秀的访客模式编写了一些类here(我的实现有点不同)。
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方法的调用,但是我有这个错误:&#34; 无法实例化抽象类&#34;。为什么在第二种情况下,accept()
没有被覆盖? MyClass应该是模板化的吗?
感谢。
答案 0 :(得分:3)
使用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
都将被路由到accept_impl
。
未经测试或编译的代码,可能包含tpyos。
答案 1 :(得分:0)
实际上你试图实现
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关键字有助于避免此类意外。