问题标签 [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.
c# - 在动态双重调度之前检查类型可见性
使用以下方式实现双重调度dynamic
:
在大多数情况下有效:
完成一项
完成了两个
但是如果子类对调度代码不可见,则会导致运行时错误:
RuntimeBinderException
类型“object”不能用作泛型类型或方法“DomainEventDispatcher.Publish(TEvent)”中的类型参数“TEvent”
这是一个人为的例子;一个更现实的事件是另一个集会内部的事件。
如何防止此运行时异常?如果这不可行,我怎样才能在Subscribe
方法中检测到这种情况并快速失败?
编辑:消除动态转换的解决方案是可以接受的,只要它们不需要知道所有子类的访问者样式类。
swift - 快速双重分派数字类型
像许多人一样,我正在尝试使用整数和浮点以及这些类型的集合。
然而 Swift 类型系统并不总是那么容易被原谅。大多数人定义了一个数字协议来处理这个问题。我想知道是否有更好的方法以及Apple如何做到这一点。
所以:
Swift 中的整数有几种类型
我们可以确认他们的类型
对相同类型的 int 进行算术运算效果很好。
- 如果类型不同,它
可能会或可能不会起作用。2. 如果其中一种类型是 Int,则操作有效,并返回将保存结果的最小类型。 更改 i1、i2 和 i3 的值以查看此内容。注意:溢出时会发生运行时错误。
例如减法(注意这里 lhs 和 rhs 的顺序很重要)
检查类型表明确实返回了最小的 Int 。
间奏曲:Apple 如何实现这一点?他们是否将所有内容都转换为 Int,进行操作然后进行强制转换?他们如何确定最小的类型? 见马丁的评论
如果我们需要这些 Int 的集合,我们就会遇到麻烦。
此时我们搜索stackoverflow并决定使用DataType协议。
这将允许我们拥有一个数组,
如果我们明确指定元素类型。
现在我们要计算一些东西 var total : DataType = 0
不确定 _ 是或应该或可能是什么。那么这个呢?
好的,所以我们为两个 DataTypes 重载函数
经过一番搜索,我们发现了双重调度。通过双重分派,我们可以使类型更加具体。
为此,我们首先扩展 Int。
现在我们可以安全地实现我们的全局函数了
并定义我们的协议
然而,现在我们必须为符合 DataType 的每个可能的类型添加一个函数到协议中。我们还必须为符合 DataType 的每种类型实现所有这些功能。
此外,我们不能使用泛型,因为这会再次导致递归。类型没有改变。
如果我们有两个恰好有 DataType 签名的常规 Int:
即使内置函数更有效,也将使用双重调度。毕竟这会跳过两个函数调用。
所以我的问题,除了那些来自间奏曲的问题,是这样的:有没有更好的方法来完成这个?一个不需要臃肿的协议(每个支持的类型的函数)并且不会不必要地回避内置的 swift 函数。
Apple 是否使用双重调度来添加 Int 和 Int16 值(见上文)?
edit1添加了 linethrough 的(见 Martin 的评论)
edit2 Swift 有一个继承自 _IntegerArithmatic 的 IntegerArithmatic 协议。
_IntegerArithmatic 定义了不应直接使用的此类函数,因为它们是实现细节(参见头文件)。
然而 FloatingPoint 协议没有这样的区别,'isEqual' 和 '==' 函数都直接在 FloatingPoint 协议中声明。为什么有区别?
java - 具有接受 Object 类的方法时的双重调度
我有一个 Mapper 类的实现,它接受 Object 作为其中一个map(Object object)
函数的参数。其余map(T t)
函数接受整数或类等。
当我尝试传递一个 int 时,它会自动装箱为 Integer 并调用map(Object object)
而不是map(Integer integer)
.
我对 Double Dispatch 做了一些研究,发现我可以使用访客模式。但这不适用于我的情况,因为我没有传递可以让它们实现接口的自定义对象accept()
。
上述方法接受每个对象。
当您有一个也接受 Object 的方法时,是否有针对 Java 对象进行双重调度的解决方案?
对这些 map() 函数的调用如下:foo(Object object) { mapper.map(object); }
这导致map(Object object)
被调用。
c# - 是否有相当于将 C# 强制转换为动态类型的 C++/CLI?
我正在扩展用 C# 编写的类层次结构,该层次结构使用 dynamic 关键字实现访问者模式(双分派),如此处所述。
这是我目前在 C# 中所做的一些非常简化的伪代码:
现在,当我扩展层次结构时,派生类可能需要处理Command
基类不知道的新特化。在这种情况下,双重调度将失败(似乎动态重载决议在尝试匹配方法时不会遍历扩展的类层次结构)。有一个简单的解决方法(在之前链接的文章中描述),它包括覆盖AcceptCommand()
派生类上的方法(复制原始实现),如下所示:
现在,为了方便起见,最近我需要使用 C++/CLI 实现的项目中的类来扩展层次结构(与非托管 WIN32 API 代码进行大量交互)。这个项目引入了几个Command
专业化,所以我需要AcceptCommand()
像在 C# 中一样覆盖 C++/CLI 类中的方法以修复双重调度,但问题是我不知道如何执行Command
对象的强制转换为C++/CLI 语法中的动态类型。这有可能吗?
java - 为什么Java双重调度不会导致无限循环?
在讲座中,我们看到了这段代码,并告诉我们它创建了双重调度,但为什么它没有创建一个无限循环?
如果 c3po.greet(c4po); 从 TranslationRobot 调用 TranslationRobot 方法
为什么 c5po.greet(c4po); 调用 CarrierRobot 中的 AbstractRobot 方法而不是 TranslationRobot 方法,然后不调用 TranslationRobot 中的 AbstractRobot 方法,然后调用 CarrierRobot 中的 Abstract 方法等等?
是什么决定了它是否调用 AbstractRobot 方法?
抽象机器人.java
CarrierRobot.Java
翻译机器人.Java
调度世界.Java
这将产生输出:
c++ - 混合双重调度和静态多态性
我敢肯定这是个坏主意。让我们假装我有充分的理由这样做。我有一棵成功使用静态多态性传递消息的节点树。至关重要的是,每个节点不能知道它连接的节点的类型,它只知道它传递的消息的类型。为了遍历树,我使用 CRTP 实现了访问者模式。这适用于树的第一级。
但是,当遍历到树的第二层时,下一个节点的类型将使用下面的 AnyNode 类擦除。我一直无法弄清楚如何从擦除类型向下转换为具体类型。下面的示例在测试中有效,但我认为它也可能非常危险,只是靠碰巧布置内存的地方工作。
我必须删除 中的访问者类型似乎有问题,AnyNode::Model<T>::acceptDispatch
这在 中是完全已知的AnyNode::Concept::accept
。但我不知道如何从概念向下转换到概念中的模型(我尝试了协变虚cast
函数,但没有奏效)。而且我无法使用虚拟方法将类型化的访问者传递给派生的模型类,因为无法对虚拟方法进行模板化。
有没有一种安全的方式来调用node.accept
和传递访问者而不必删除访问者的类型然后将其静态转换回来?有什么方法可以Model<T>
在运行时将概念向下转换为 a 吗?有没有更好的方法来解决这个问题?是不是有一些疯狂的 C++11 新方法可以解决这个问题,可能是 SFINAE?
编辑这里是访问者基类,以及派生访问者的示例。派生的访问者由客户端代码实现(这是库的一部分),因此基类无法知道将实现什么访问者。恐怕这会分散中心问题的注意力,但希望它有助于解释这个问题。此处的所有内容都有效,除非->accept( visitor )
在outlet_visitor::operator()
.
c++ - 如何使用多态参数动态调用函数
我怎样才能动态地调用表单的函数:childA.function(childB)
而它们的静态类型都是父母?
并提供更多详细信息:
我有一个物理项目,我需要计算 2 个分子的势能。但是我有两种类型的分子,LC 和 Col,每种类型都有自己的参数和东西,但是我希望能够动态地调用每个分子的潜力。
所以我尝试了这个:
但是我得到了 4 的结果,因为事实证明该函数是静态调用的,这意味着由于 mol1 的静态类型是 Molecule,所以调用的函数是:
并不是
无论如何在不使用 typeid 的情况下动态调用函数(在 OOP 设计中)?
完整答案:
在 Peter 的建议下进行调查后,这被证明是经典的双重调度问题,完整的解决方案就是在虚拟内部调用另一个虚拟,如下所示:
这确实根据需要返回 3 。
java - 下面的程序可以被认为是双重调度的例子吗?
上述程序的输出是:
在市场上搜索产品。
在商店中搜索手机。
因此,输出暗示调用 market.buy(new Product()); 和 shop.buy(new Mobile()); 由调用它的对象的引用和传递给它的参数来解决。所以如果它同时使用这两个东西来调度一个函数调用,我们可以称之为双重调度吗?还是我误解了双重派遣一词?
c++ - 访问者和双重分派而不覆盖 C++ 中的“接受”方法
好的:这是我的问题:我有一个基础合成类,它接受一个访问者,然后迭代它的节点。奇迹般有效。但是,我必须使用从这个合成派生的,并认识到我必须重写派生类中的“accept()”方法才能进行正确的双重调度(我不明白)。
这带来了两个缺陷:第一,我必须打破基础的隐藏结构,第二,我必须重复代码。为了清楚起见,这是我的伪代码:
有什么优雅的解决方案吗?谢谢 !
编辑:将“virtual”添加到“accept()”以使其更精确......
c++ - 为什么我们在访问者模式中需要 accept() 以及为什么我们不能直接调用 visitor.visit()?
我正在修改前一段时间使用的访客模式。我们有一个基类 Element,它有虚方法 accept(Visitor) 并且这个方法在所有继承自 Element 的类中被覆盖。在任何派生类中,accept() 所做的只是调用visitor->visit(*this)。现在,当客户端运行代码时,他/她会执行以下操作:
为什么客户不能像这样调用visitor->visit(element):
调用 element.accept(visitor) 后又调用 visitor.visit(element) 有哪些有用的信息?这使得访问者模式的使用变得繁琐,并且在元素类的所有层次结构中都需要额外的代码。
那么有人可以在这里解释 accept() 的好处吗?