强制转换抽象类的 n 个实现的静态类型,使其与其动态类型相对应 - 至少使用代码

Cast the static types of n Implementations of an Abstract Class to correspond with their dynamic Type - with at least code as possible

提问人:Cherry Toska 提问时间:4/26/2020 更新时间:4/28/2020 访问量:61

问:

我有一个与 Actors 一起使用的库。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++ 设计模式 C++17

评论

0赞 Igor Tandetnik 4/26/2020
您可以添加一个 到 ,并让派生类通过调用 来实现它。为什么你又需要每个类都有一个同名的函数,但不能使这些函数虚拟?这是一个奇怪的要求。virtual staticFuncWrapper() = 0;ActorstaticFunc()

答:

0赞 Michaël Roy 4/28/2020 #1

是的,您可以使用 C++ 20 中添加的“重载()”结构/函数。幸运的是,它的实现时间很短,可以在 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);

评论

0赞 Cherry Toska 4/29/2020
我相信除了这个之外,没有其他方法可以用更少的代码来编写它。
0赞 Michaël Roy 4/30/2020
我也是。我也相信这是使用访客的唯一理智方法。
1赞 Cubbi 5/22/2020
它没有添加到 C++20 中。注释只是指出 C++20 中不需要第二行,它变成了单行。