C ++:覆盖从模板类派生的虚拟纯函数

时间:2016-11-21 20:45:56

标签: c++ c++11 override variadic-templates

我根据这个优秀的访客模式编写了一些类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应该是模板化的吗?

感谢。

2 个答案:

答案 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 ++中,它与方法名称不同 - 一个具有模板限定而另一个没有。此外,templatevirtual是方法的不兼容说明符,您应该有错误

class MyClass : ... {
  ...
  template<typename... Types>
  virtual void accept(Visitor<Types...>& visitor);
};

error: templates may not be ‘virtual’

override C ++ 11关键字有助于避免此类意外。