简单明了:标签调度相比于普通的重载解析有什么优势?
这两种都是编译时过程,对吧?因此我认为不应该有'性能优胜者'。每个标签调度案例都应该能够在一定程度上被重新编写/重构成正常的重载(可能通过添加多个类型实现),对吧?
除了工作方式和选择候选项的不同之外,为什么我应该更喜欢标签调度而不是重载解析,并在哪些情况下使用?
简单明了:标签调度相比于普通的重载解析有什么优势?
这两种都是编译时过程,对吧?因此我认为不应该有'性能优胜者'。每个标签调度案例都应该能够在一定程度上被重新编写/重构成正常的重载(可能通过添加多个类型实现),对吧?
除了工作方式和选择候选项的不同之外,为什么我应该更喜欢标签调度而不是重载解析,并在哪些情况下使用?
标签分派(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
的实现方式。
通过适当的特性类,标签可以与类型关联,甚至包括基本原始类型。例如,不可能将指针类型作为某些迭代器概念的子类。但是,模板化的特性类可以将其与所需的标签相关联。因此,基于标签的分派增加了灵活性,允许构建一个分派方案,该方案不必由涉及的类型已经定义。