提问人:Cherry Toska 提问时间:4/26/2020 更新时间:4/28/2020 访问量:61
强制转换抽象类的 n 个实现的静态类型,使其与其动态类型相对应 - 至少使用代码
Cast the static types of n Implementations of an Abstract Class to correspond with their dynamic Type - with at least code as possible
问:
我有一个与 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)
答:
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 中不需要第二行,它变成了单行。
评论
virtual staticFuncWrapper() = 0;
Actor
staticFunc()