问题标签 [double-dispatch]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
3 回答
237 浏览

c++ - C ++中的双重调度不起作用

我正在用 C++ 编写一个类似流氓的游戏,并且遇到双重调度问题。

然后在派生类中:

然后我尝试使用代码:

创建单元格的位置如下:

当我尝试碰撞播放器和墙壁时:

玩家与基类发生碰撞,但没有与墙发生碰撞。我究竟做错了什么?

0 投票
2 回答
129 浏览

objective-c - 如何在 Objective-C 中模拟双重调度

我正在尝试在 Objective-C 中模拟双重调度。

我知道 Objective-C 不支持函数/方法重载。但是你能效仿吗?

任何想法。

0 投票
2 回答
102 浏览

c++ - 多态二元函数

我有三个形状类,,,,我Circle有功能SquareConvexPolygon

我想要一个多态函数

调用上面特定于形状的方法来填充交点矩阵。

我认为在 c++ 中不可能完全做到这一点,但我可以接受任何其他解决方案,只要我可以在不更改计算交集矩阵的代码的情况下添加新的形状类型。

0 投票
1 回答
783 浏览

c++ - C++ 双分派示例

我将此代码作为使用双重调度的示例,但我并不真正理解代码的一部分。创建“抽象类”打印机,为什么我需要添加:

据我了解,在运行时 p.print(docA);会将我发送到virtual void print(Document *d)myPrinter,然后d->printMe(this)将我发送到 PDFDoc 的 printMe,然后它会在运行时调用virtual void print(PDFDoc *d)我的打印机?

那么为什么要定义

抽象类是必需的吗?

0 投票
0 回答
319 浏览

c++ - 具有运行时多态性的 C++ 双重分派?

是否可以使用运行时多态性执行双重调度?

假设我有一些类,其中一些类可以添加/相乘/等等,我想将它们动态地存储在另一个在运行时执行类型擦除的类中。然后说我想对该类中保存的数据执行基本操作。

处理这个问题的方法(据我所知)是使用双重调度来专门化操作。但是,我遇到的所有解决方案都依赖于您拥有大量类型的事实,然后在运行时使用虚函数调用或dynamic_casts, if-else, 和 RTTI 来推断类型。因为类中保存的数据直到运行时才知道,所以我无法创建一堆虚拟方法或对类型进行强力检查。所以我认为访问者模式将是最好的解决方案,但即便如此,我似乎也无法确定这是否可能。

我有一个包装类,它包含一个指向嵌套多态类的智能指针,以实现类型擦除和运行时多态,但我不知道是否可以使用访问者模式对此进行双重调度。

请注意,下面的代码是不完整的,它只是展示了我的思考过程。

我也研究过使用函数指针、模板特化和静态类型 ID 来实现双重分派,但我似乎无法弄清楚如何使其工作。

这甚至可能吗?


编辑

根据下面的评论,为了更具体并提供更多背景知识,我正在使用模板类,这些类使用模板函数来执行加法和乘法等基本操作。但是,我还想将这些模板类存储在向量中,因此类型擦除。现在,如果我想在执行类型擦除后对这些类进行操作,我需要一些方法来推断模板化函数的类型。但是,由于我无法轻松地从 中获取内部保留类型Wrapper,我希望有一种方法可以对Wrapper::Model<T>类中保留的数据调用正确的模板函数,无论是访问者模式、静态类型 ID , 任何。


更具体地说,我正在使用类来进行延迟评估和符号计算,这意味着我有诸如Number<T>, 可以是Number<int>,Number<double>等的类和诸如 ,Variable之类的类Complex<T>以及用于各种操作的所有 TMP 组合,例如Add<Mul<Variable, Variable>, Number<double>>, ETC。

我可以在编译时很好地处理所有这些,但是我需要能够将它们存储在一个向量中——比如std::vector<Wrapper> x = {Number<int>, Variable, Add<Number<double>, Variable>};. 我对此的最佳猜测是执行类型擦除以将表达式存储在 polymorphicWrapper中。这具有双重职责,以启用符号表达式的运行时解析支持。

但是,我编写的用于处理加法的函数,例如

不能接受Wrapper和拉出类型(由于类型擦除)。但是,我可以将 插入WrapperAdd表达式类中,这意味着我可以携带隐藏类型。问题是当我真正开始评估类似Add<Wrapper, Wrapper>. 为了知道这是什么结果,我需要弄清楚里面到底是什么,或者按照双重调度的方式做一些事情。

主要问题是与我的问题最接近的双重分派示例,例如 SO 上的这个问题,依赖于我可以写出所有类的事实,例如Shapes, Rectangles。由于我不能明确地这样做,我想知道是否有一种方法可以执行双重调度,以根据Model<T>上面类中保存的数据来评估表达式。

0 投票
1 回答
86 浏览

c++ - 将 shared_ptr作为 shared_ptr传递

我目前有以下结构

class A

class B : public A

class C : public A

我在和中定义了虚拟方法,A并且B正在C覆盖它们。方法是这样的

bool C::CheckCollision(shared_ptr<B> box);

bool B::CheckCollision(shared_ptr<C> triangle);

我还有一个shared_ptr<A>存储所有游戏对象的向量。问题是我无法执行以下操作

我收到一条错误消息,指出参数列表与重载函数不匹配。shared_ptr<A>当我试图通过我期望的地方时shared_ptr<B>,这是有道理的shared_ptr<C>,但是我该如何解决这个问题?还有另一种方法吗?

0 投票
1 回答
88 浏览

c# - 重载方法而不修改类

我可以访问一个无法修改的类结构,如下所示:

再说一次,我不能修改它!这些都具有单独的属性,例如RadiusFirstPointLastPoint等,以及一些共同的属性。

我想创建一个接受Graphics对象的方法,并且根据对象的类型,将运行一个ToJson方法:

起初我以为我可以巧妙地重载该ToJson方法:

但是,这当然适用于ToJson(Graphics)每次的通用重载。

我确定我可以执行以下操作:

或创建一个字典来降低每种类型的复杂性,但这并不是最好的做事方式


我考虑过的

我已经考虑过是否可以在每个对象周围使用一些通用的包装方法(例如,new JsonGraphics(g).ToJson()),但我不想自己执行任何手动类型检查。

我已经查看了双重调度和访问者模式,但我不确定它们是否满足我的要求,因为它们看起来我必须修改这些类(或者我可能只是没有完全理解它们),并且(有点明显,但是) 泛型也基本上不在窗口中,因为它们需要我提前知道Graphics这是什么类型的对象。


那么两个问题:

除了使用某些 Dictionary 或其他类似的东西之外,还有更好的方法if (g is Type)吗?

如果我可以修改类,模式会怎样?在这种情况下这是不可能的,但是在我可以的情况下,双重调度/访客是最好的方式吗?

0 投票
1 回答
65 浏览

c++ - 使用模板代码转发声明类

我正在尝试为 C++ 中的消息接口实现双重调度模式。但是,我发现由于必须转发声明每条消息,我必须在处理程序类中过于冗长。

我正在寻找一种方法来构造文件以省略前向声明。

我知道我可以使用所有可用消息的元组来模板 MessageHandler 类。然而,我发现这不够简单,并寻找更简单 - 可解释 - 方法。

在实际代码中,我处理了 20 多条消息。我对处理程序类的冗长没意见,前向声明有点“多”。

有什么办法可以重组这个吗?当然,由于 MessageHelper 类是模板化的,因此我受到了限制。这限制了我转发声明 MessageHandler 类。

谢谢!

0 投票
1 回答
146 浏览

c++ - 我们在 C++ 中需要双重调度/访问者到底发生了什么

我了解解决方案的实现和双重调度/访问者模式,但是我不明白在编译时和运行时会发生什么,我们需要这种模式。

例如这段代码:

如果没有双重分派,对 by_const_ref 的第二次和第四次调用将不会将 B() 解析为 A 对象。

从这篇文章:https ://en.wikipedia.org/wiki/Double_dispatch#Double_dispatch_in_C++我知道它涉及名称修改和编译时间以及运行时的 vtable 解析,但我没有找到确切的方法。

对于名称修改部分,我查看了编译后的对象,但没有发现任何特别之处。

对于 vtable,我用 g++ -fdump-lang-class 转储了它,看起来那里也没有太多信息。

因此我的要求。我想了解到底发生了什么,也许如何检查这种行为(使用像 nm 这样的工具,检查 vtable,机器代码?)

0 投票
1 回答
93 浏览

clojure - “ISA”是怎样的?基于多方法而不是 instanceof 的语法糖?

我从clojure 网站举个例子。

这个功能很酷。我试图了解为什么这优于(例如)java 中基于 instanceof 的实现的技术原因。在我看来,它在功能上基本上等同于更好的语法。

为什么 multimethods 被认为是基于访问者模式的双重调度的一个很好的替代方案,而 instanceof 在它们看起来基本上在做同样的事情时却不是?