标签分派相对于普通重载解析的优势

11

简单明了:标签调度相比于普通的重载解析有什么优势?

这两种都是编译时过程,对吧?因此我认为不应该有'性能优胜者'。每个标签调度案例都应该能够在一定程度上被重新编写/重构成正常的重载(可能通过添加多个类型实现),对吧?

除了工作方式和选择候选项的不同之外,为什么我应该更喜欢标签调度而不是重载解析,并在哪些情况下使用?


7
通过重载实现基于标签的分派。 - Arunmu
2个回答

11

标签分派(Tag dispatching)基本上是一种用于找到正确重载函数的技术。因此,在技术上它只是重载。

Boost网站来看:

标签分派是一种使用函数重载基于类型属性分派的方法,通常与特性类(hand in hand with traits classes)一起使用。

您可以在标准库algorithm头文件中随处看到它被使用。举个例子,考虑有一个算法AlgoX,对于提供随机访问(例如vector)的容器,可以更高效地执行,而对于提供双向访问(list)的容器,则没有那么高效。因此,为了基于迭代器类型(iterator type)选择算法,可以使用iterator_traits进行标签分派。

template <typename Iter>
void AlgoXImpl(Iter first, Iter last, bidirectional_iterator_tag) {
  //.....Algo specialized to bidirectional iterators
}

template <typename Iter>
void AlgoXImpl(Iter first, Iter last, random_access_iterator_tag) {
  //.....Algo specialized to random access iterators
}

template <typename Iter>
void AlgoX(Iter first, Iter last) {
  if (first == last) return;
  AlgoXImpl(first, last, typename iterator_traits<Iter>::iterator_category());
}

如您所见,对于一个简单的思维来说,这只是运算符重载的示例,因为这些类别本质上是不同类型。

对于一个更实际的例子,您可以查看 std::rotate 的实现方式。


1
标签分派被广泛使用的事实并不能回答为什么要使用它的问题。原帖作者正确地指出,在他控制的类型层次结构中,可以通过普通的方法重载轻松实现其效果。因此,决定性的论据是实现一个与类型定义解耦的自定义分派方案。请参见下面我的答案。 - Thomas B Preusser
我的回答要点基本上是前4-5行,而不是它在STL中使用。 - Arunmu
补充这个答案的一个重要问题:相对于普通重载,标签分派是否更快? 我认为不是因为它们都是在编译时实现的,但我还是想问一下,以确保。 - Dean
1
@Dean 是的,它们都是在编译时实现的(除非我们谈论存储过程或共享库中的符号)。标记调度只是给函数重载的一个特定用例命名,我们试图使用某些类型特征来选择最佳重载。 - Arunmu

2

通过适当的特性类,标签可以与类型关联,甚至包括基本原始类型。例如,不可能将指针类型作为某些迭代器概念的子类。但是,模板化的特性类可以将其与所需的标签相关联。因此,基于标签的分派增加了灵活性,允许构建一个分派方案,该方案不必由涉及的类型已经定义。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接