C++:根据参数的类型调用派生类的正确方法

cod*_*nk1 5 c++ virtual overriding c++11

假设我们有一个基类及其两个派生类; 基类拥有一个方法execute,每个派生类使用不同类型和数量的参数实现此方法的不同版本; 我不能使用虚方法,因为签名应该对每个派生类完全相同; 我的目标是提供一个基本执行方法,它接受任何类型的参数,减去它们的类型,并将它们分派到右派生类中的正确方法; 我看了一下Visitor模式,但我正在寻找一个更灵活,更优雅的解决方案;

编辑:我想将这些类存储在一个向量中,所以我需要一个基类

这是我的尝试(我不知道在基本执行的主体中放入什么)在gcc 4.5下:

class Base {

  public:

  Base();
  ~Base();

  template<typename ...Args>
  void execute(Args... arg)
  {
    //calls the right method
    //execute(int i) or execute(int i, float f)
    //as Args are int or int and float
  }

};

class DerivedA : public Base
{

  public:

  DerivedA();
  ~DerivedA();

  void execute(int i){ /*do something with i*/}

};

class DerivedB : public Base
{

  public:

  DerivedB();
  ~DerivedB();

  void execute(int i, float f){/*do something with i and f*/}

};

void test()
{
  Base* b1 = new DerivedA();
  Base* b2 = new DerivedB();

  int i = 5;
  b1->execute(i); //should call DerivedA.execute(int i)
  float f = 5.0f;
  b2->execute(i, f); //should call DerivedB.execute(int i, float f)

}
Run Code Online (Sandbox Code Playgroud)

cel*_*chk 5

以下使用基类和派生类之间的中间类:

#include <utility>
#include <iostream>
#include <stdexcept>

template<typename... Args> class Intermediate;

class Base
{
public:
  virtual ~Base() {}

  template<typename ...Args>
  void execute(Args... args)
  {
    typedef Intermediate<Args...>* pim;
    if (pim p = dynamic_cast<pim>(this))
    {
      p->execute(std::forward<Args>(args)...);
    }
    else
    {
      throw std::runtime_error("no suitable derived class");
    }
  }
};

template<typename... Args> class Intermediate:
  public Base
{
public:
  virtual void execute(Args ... arg) = 0;
};

class DerivedA:
  public Intermediate<int>
{
public:
  void execute(int i)
  {
    std::cout << "DerivedA: i = " << i << "\n";
  }
};

class DerivedB:
  public Intermediate<int, float>
{
public:
  void execute(int i, float f)
  {
    std::cout << "DerivedB: i = " << i << ", f = " << f << "\n";
  }
};

int main()
{
  Base* b1 = new DerivedA();
  Base* b2 = new DerivedB();

  int i = 5;
  b1->execute(i); //should call DerivedA.execute(int i)
  float f = 5.0f;
  b2->execute(i, f); //should call DerivedB.execute(int i, float f)
}
Run Code Online (Sandbox Code Playgroud)