自动调用 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);
}
我正在开发一个在 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);
}