c++ - 将抽象类的 n 个实现的静态类型转换为与其动态类型相对应 - 至少使用代码
问题描述
我有一个与演员一起工作的图书馆。Actor 实现的接口在抽象类Actor中定义,并且 Actor-library 与 Actor* 一起使用,但是为了使用另一个库,我需要为每个类实现静态函数,而我的 Actor-library 自然认为每个实现都有Actor 的静态类,所以为了解决这个问题,我为示例情况创建了以下指针变体和包装器:
ActorImpls = std::variant<
ActorType1*,
ActorType2*,
ActorType3*,
ActorType4*,
>;
以及通过检查动态成员字段将静态类型重新解释为与动态类型相同的强制转换函数:
ActorImpls staticCorrespond2Dynamic(Actor* cl){
std::string s = cl->getDynamicName();
if(s.compare("Dynamic ActorType1")==0){
ActorType1* x = reinterpret_cast<ActorType1*>(cl);
...
现在我可以使用访问者为给定的 ActorImpls 调用静态函数,但我将始终调用具有相同名称的函数,它将是 ActorType1->staticFunc() 或 ActorType2->staticFunc(),有没有办法使包装器使用更少的代码?
对于静态打印函数,访问者看起来像这样:
struct VisitPrintStatic{
VisitPrintStatic() {}
void operator()(ActorType1* x){x->printStaticName();}
...
我还尝试过什么:使用可变参数模板实现,主要问题是在运行时获取任何信息几乎是不可能的。有以下类型的函数需要考虑,它们在所有参与者中都具有相同的名称:
Actor* ActorX = new ActorTypeX;
ActorX->staticFunc() //where ActorTypeX must be reinterpreted from Actor* to ActorTypeX*
ActorTypeX::staticFunc(ActorTypeX& obj, Args...) //(same as above)
解决方案
是的,您可以使用 C++20 中添加的 'overloaded()' 结构/函数。幸运的是,它的实现非常短,并且可以在 C++17 中运行。
来自以下示例: https ://en.cppreference.com/w/cpp/utility/variant/visit
// helper type for the visitor #4
template<class... Ts> struct overloaded : Ts... { using Ts::operator()...; };
template<class... Ts> overloaded(Ts...) -> overloaded<Ts...>; // not needed as of C++20
您的呼叫站点变为:
std::visit(overloaded {
[](auto& actor) { StaticFun(actor); },
}, ActorImpls);
推荐阅读
- c++ - 错误:找到一个或多个多重定义的符号
- flutter - 为 Flutter 中动态生成的 TextFormField 生成 TextEditingController
- javascript - 如何通过 useFormik Hook 使用 Radio Group
- python - 从 create_engine (postgresql) 获取列
- python - matplotlib lib 引发归因错误:模块“matplotlib.rcsetup”没有属性“_validators”
- python - 删除字符串中的转义字符,如换行符、制表符、回车符等
- python-3.x - Python3:以编程方式列出虚拟环境中所有已安装的包和版本
- php - 以php形式动态发送输入和选择字段
- idris - 在 Idris 中,当类型参数已经在别处定义时,为什么我们需要将类型归于类型参数?
- python-3.x - collectstatic whitenoise 在部署到 heroku 时看不到我现有的文件