问题标签 [tag-dispatching]
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++ - 在 C++ 中使用 enum 而不是 struct 进行标记调度
让我们std::unique_lock
从标准库中实现:
有没有理由不/不能/不应该使用枚举而不是结构来实现标签调度?如:
后者更简洁。
我能想到的使用结构的唯一优点是继承(例如,迭代器标签)。但在所有其他情况下,为什么不使用枚举呢?
c++ - 将 C++ 模板“if constexpr”转换为旧的“标签调度”方法
我对模板概念很陌生,例如SFINAE
ortag dispatching
并且一直在阅读一些关于它的文章和示例,这些文章和示例对我的方法没有帮助。因此,如果有人可以提供帮助,我将不胜感激。
我的目标是拥有 1 个单一的解析函数,它会在将数据传递给其他一些函数以根据模板T
类型进行特定解析之前做一些事情。
在附加的代码中,这是我想要的一种行为。我在这里使用if constexpr
的是一个 C++17 功能,在我使用的 C++ 版本中不可用。
我认为为此目的,乍一看似乎template specialization
是最好的解决方案,但这不是我想要的。
我认为为此目的tag dispatching
将是一个很好的方向,但我不确定type_traits
当我有自定义类型时如何准确地做到这一点,因为它总是像我有 2 个选项 a true_type
or false_type
,但在下面的代码中我有 3 种情况有更多的潜力。
我真的很感激一些例子或方向,请告诉我做我正在寻找的最佳方法是什么。甚至一些要阅读的文章也会很棒。
提前致谢!
工作代码示例:
class - 我怎样才能让这个调度电话工作?
我正在尝试熟悉 Ada 中的面向对象。几个月前,您的网站帮助我解决了另一个 OO 问题,我希望您愿意再次提供帮助。
情况:我有一个抽象类型“token”和两个派生类型“otoken”和“vtoken”。我想将 2 个派生类型放在同一个数组中并让它们正确调度。
我的教科书建议将数组声明为包含指向 token'class 的指针,这迫使我从头到尾处理点。下面是我的程序的精简版本,但它不会编译,因为编译器说我的调度调用是“模棱两可的”</p>
当我用我的 GNAT Ada 95 编译器编译它时,我收到错误消息:
换句话说,它无法将这两个函数识别为替代调度调用。如果你能建议我,我将不胜感激,因为我已经坚持了好几天了。
c++ - SFINAE 和标签调度的区别
在此视频中https://youtu.be/Vkck4EU2lOU?t=582 “标签调度”和 SFINAE 作为替代方案,允许实现所需模板功能的选择。
这是对的吗?“标签调度”不是使用 SFINAE 吗?如果它是正确的,那么 SFINAE 和标签调度之间究竟有什么区别?
c++ - 多个遗产断言的可变参数模板 - “...用 3 个模板参数重新声明...”
我正在尝试std::is_base_of
为我的 AVR 编程实现我自己的(avr-gcc 尚不支持。我从 cppreference 页面上可能的实现<type_traits>
中获得灵感,它适用于单一类型检查。但是,我想要实现的是静态对一个基类的多种类型的继承执行有效性检查。
为简单起见,我 std::is_base_of
用于下面的实际检查,但是我的实际解决方案与上面链接的 cppreference 页面中的内容接近。
我将使用它进行标签调度,更具体地说是允许任何顺序的选项标签。
选项标签
单一遗产验证器结构
尝试多次检查(上述isBaseOf
声明的补充)
这不起作用。据我所知,我无法使用不同数量的类型重新声明模板。但是,我在最后一个模板构造中至少需要两种类型。我尝试将 TBase 作为唯一参数并将值设置为 true,但同样的问题仍然存在:错误:使用 3 个模板参数重新声明
用法
如前所述,这仅限于单次检查。由于我的类(此处未显示)对任意数量的选项标签使用可变参数模板(并且 avr-gcc 不支持constexpr
函数中带有 for 循环的完整 c++14),我希望能够使用参数解包并仍然检查所有选项标签都继承了我的基本标签 ( tOption
)。
使用函数 - 丑陋和不需要的
我让它使用一个函数而不是另一个结构来工作,但我认为这很令人困惑。我宁愿有一种方法来解决整个递归(静态)堆栈中的问题。此外,这迫使我构建每个标签,这不是很整洁的 IMO。
有没有办法用其他数量的参数重新定义结构模板,例如上面的多次检查尝试?
c++ - 当其中一个函数实际上是函数对象时,修复或替代 ADL
在下面的代码中,命名空间中的独立组件S
具有自己的定义Big
和Small
类型,以及将其拆分为 s 集合的split
函数。Big
Small
S
还提供了另一个函数 ,work
它利用split
, 并且旨在由其S
自身以及其他依赖组件使用, 例如命名空间中的组件,D
假定它们提供自己的定义Big
和Small
以及它们自己的split
定义将通过 ADL 识别。¹
好吧,实际上S::split
是一个函数对象,而不是一个函数²,
所以 ADL 不起作用。
关于如何解决这些需求的任何建议?
从评论中可以看出,Niebloids 和/或tag_invoke
代表了我的问题的答案。我真的很想更多地了解这些概念。
目前,我对 Niebloids 的理解(我正在阅读Eric Niebler 的这篇博客)是它们是函数对象(当它们在范围内时)阻止 ADL,因此“集中”所有指向不合格自由函数的函数调用与 niebloid 同名;然而,它们operator()
依赖 ADL 将调用转发到适当的自由函数。因此,看起来我的示例代码S::split
中作为函数对象和D::split
作为自由函数之间的对比无法由 niebloids 解决,除非我创建S::split
了一个自由函数(在这种情况下,ADL 在我的简单场景中就足够了)。
¹ 最初是在andwork
中定义的,上面的代码是我尝试的重构,在此期间我遇到了所描述的问题。S
D
² 这样做的原因是,S::split
它在多个上下文中使用S
,它有一些重载operator()
,最重要的是,它经常作为对象传递,非常方便。
c++ - 在 constexpr 分支中使用枚举类值
下面的代码打印val2
在两个f()
调用上。f()
根据枚举值执行特定分支的正确方法是什么?
lambda - C++ 17 中类型标记 lambda 调度的最短语法
我被限制使用 C++17,我想通过传入类型标记将类型传递给 lambda,我可以在 C++20 和 C++17 中通过以下方式。
是否有比 typename decltype(tag)::type 更短的语法可以用来从 C++ 17 中的类型标记中提取类型?
c++ - 基于 conditional_t over is_floating_point 的标签调度
对于简单的标记调度实现,我得到了一个奇怪的调用函数“Equals”,该函数在模板定义中既不可见,也不通过依赖于参数的查找找到。
我究竟做错了什么?