自动调用 class 静态函数 C++11

Automated call to class static functions C++11

我正在开发一个在 ESP32 微控制器 (c++11) 上执行的项目,我想实现一个 class 方法,该方法可以采用 Class 引用(不是实例那些 classes) 作为参数以执行那些 classes.

的静态方法

我设法实现了以下工作解决方案:

#include <iostream>

    class Model
{
public:
    static void foo()
    {
        std::cout << "Model.foo invoked" << std::endl;
    };
};

class ModelA: public Model
{
public:
    static void foo()
    {
        std::cout << "ModelA.foo invoked" << std::endl;
    };
};

class ModelB: public Model
{
public:
    static void foo()
    {
        std::cout << "ModelB.foo invoked" << std::endl;
    };
};


class Manager
{
public:

    template <class T = Model>
    void callFoo()
    {
        T::foo();
    }

    template<class T = Model, class ... args>
    void setup()
    {
       callFoo<T>();
       callFoo<args...>();
    }

};


int main()
{

    Manager manager;
    manager.setup<ModelA, ModelB>();

    return 0;
}

输出符合预期结果:

ModelA.foo invoked

ModelB.foo invoked

但我觉得这种方法充其量只是一个糟糕的 hack...

有人有更好的方法来实现这个(最好不使用模板)吗?

提前致谢。

文森特。

您想使用类型classes 作为参数。当前在 "C++".

中不可用

但是,对于您的具体情况,由于所有静态方法都具有相同的函数原型或函数签名,您可以采取一些变通办法。

首先,将每个静态方法改为虚方法:

#include <iostream>

class Model
{
  public:
    virtual Foo(void* Args)
    {
      str::cout << "method Model.DoFoo( ) invoked. << std::endln;
    } // DoFoo

}; // class Model

class ModelA: Model
{
  public:
    virtual Foo(void* Args)
    {
      str::cout << "method ModelA.DoFoo( ) invoked. << std::endln;
    } // DoFoo

}; // class ModelA

class ModelB: Model
{
  public:
    virtual Foo(void* Args) override
    {
      str::cout << "method ModelB.DoFoo( ) invoked << std::endln;
  } // DoFoo

}; // class ModelB

其次,添加一个本地函数,而不是方法,以生成每个 class 的实例作为结果:

 Model* ModelFactory( )
 {
   Model* M = new Model ( );
   return M;
 } // ModelFactory

 Model* ModelAFactory( )
 {
   Model* M = new ModelA( );
   return M;
 } // ModelFactory

 Model* ModelBFactory( )
 {
   Model* M = new ModelB ( );
   return M;
 } // ModelFactory

三,您的 Manager class,而不是 "variadic" 或“...”参数,您将添加一个矢量作为单个参数,以存储对那些工厂的引用函数。

以及存储该向量的参数。

#include <vector>

typedef
   Model* (*Factory) (void* Args);

class Manager
{
  public:
     std::vector<Factory>* Factories;

    void setup(std::vector<Factory>* AFactories)
    {
      this.Factories = AFactories;
    } // setup

} ; // class Manager

请注意,工厂作为类型classes 参数工作。

四、Manager class 的一个方法,从向量中检索每个工厂,执行它,生成一个实例,调用替换虚方法,然后处置该实例。

class Manager
{
  public:
     std::vector<Factory>* Factories;

    void setup(std::vector<Factory>* AFactories)
    {
      this.Factories = AFactories;
    } // setup

    void run(void* Args)
    {
      for (Factory EachFactory : this.Factories)
      {
         Model* M = EachFactory( );
           M->Foo(Args);
         delete M;
      } // for
    } // void

} ; // class Manager

五、构建实例:

int main( )
{
  Manager* M = new Manager( );

  // prepare compiletime list of classes
  std::vector<Factory>* Factories =
    new std::vector<Factory>*(2);

  Factories->insert(&ModelAFactory);
  Factories->insert(&ModelBFactory);

  // assign list to Manager
  M->setup(Factories);

  // execute each class method
  // with same parameters
  M->run( nullptr );

  // drop list
  delete Factories ( );

  delete M;
} // main

你的Model class和subclasses可能还有其他操作,完全不相关,仍然不冲突,将static方法替换为virtual 方法。

请注意,较新版本的 C++ 标准可以使用概念和可变参数的模板做类似的事情。

如果您想根据该类型的引用分派任何类型的静态成员函数,您可以通过(稍微)滥用函数模板参数推断轻松地做到这一点:

template <typename T>
void call(T const& = *static_cast<T const*>(nullptr)) {
  T::foo();
}

struct Magic {
  static void foo() {}
};
struct MoreMagic {
  static void foo() {}
};

int main() {
  call<Magic>();
  call(MoreMagic());
  MoreMagic m;
  call(m);
}