Приведите типы * stati c n реализаций абстрактного класса, чтобы они соответствовали их динамическому типу c - как минимум с кодом, насколько это возможно - PullRequest
0 голосов
/ 26 апреля 2020

У меня есть библиотека, которая работает с актерами. Интерфейс для реализации Actor определен в абстрактном классе Actor , и библиотека акторов работает с Actor *, но для использования другой библиотеки мне нужно реализовать функции stati c для каждого класса, а мой actor-library естественно думает, что каждая реализация имеет класс Actor stati c, поэтому для решения этой проблемы я создал следующий вариант указателей и оболочки для примера:

ActorImpls = std::variant<
    ActorType1*,
    ActorType2*,
    ActorType3*,
    ActorType4*,
>;

И функция приведения, которая интерпретирует тип stati c таким же, как и тип Dynami c, путем проверки поля члена Dynami c:

  ActorImpls staticCorrespond2Dynamic(Actor* cl){
             std::string s = cl->getDynamicName();
                if(s.compare("Dynamic ActorType1")==0){
                    ActorType1* x = reinterpret_cast<ActorType1*>(cl);
                ...

Теперь я могу вызывать функции stati c для данный ActorImpls с посетителем, но я всегда буду вызывать функцию с тем же именем, это будет ActorType1-> staticFun c () или ActorType2-> staticFun c (), есть ли способ заставить упаковщик работать с меньшим количеством кода?

Посетитель выглядит примерно так: c -print-fun c:

struct VisitPrintStatic{
        VisitPrintStatic() {}
        void operator()(ActorType1* x){x->printStaticName();}
        ...

Что еще я пробовал: при реализации шаблонов variadi c основная проблема заключается в том, что практически невозможно получить любую информацию о времени выполнения. Есть следующие типы функций, которые нужно учитывать, они имеют одинаковое имя для всех действующих лиц:

Actor* ActorX = new ActorTypeX;
ActorX->staticFunc() //where ActorTypeX must be reinterpreted from Actor* to ActorTypeX*
ActorTypeX::staticFunc(ActorTypeX& obj, Args...) //(same as above)

1 Ответ

0 голосов
/ 27 апреля 2020

Да, вы можете использовать структуру / функцию 'overloaded ()', добавленную в 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);
...