Tag dispatching

Tag dispatching


Tag dispatching is a technique for compile time dispatching between a few overloaded functions by using the properties of a type. This technique usually involves some kind of type traits.

Suppose you needed to carry out some task, in the form of a work() function. What is interesting is that it is possible to write two different such functions: one that is able to work pretty fast (by using bitwise operations for example), and a normal – slow – one (which uses regular arithmetic). The fast approach will only work with some types (say, integral types like int, long, etc), while the regular implementation is fine for just about any type. The thing is, overloading these two functions for all the types in the system is pretty much impossible. And even if it was, maintaining such a thing is surely not going to be any fun. So we’re looking for an elegant solution.

Obviously, tag dispatching can be the answer. Otherwise why would I  be telling this long story?

Most C++ software systems already contain some form of a traits mechanism. We would like to add another typedef to these traits – one that will tell us exactly whether we can use the fast implementation, or not. Once the traits have been set up, all we need to do is overload the two distinct work_dispatch() functions, and have a main work() function which will actually carry out the traits-based dispatch. Here is how the implementation could look like:

1#include <iostream>
2 
3struct fast_speed_tag {};
4struct slow_speed_tag {};
5 
6template <typename T>
7struct traits { // default
8    typedef slow_speed_tag speed;
9};
10 
11template <>
12struct traits<int> { // we would do the same for long etc
13    typedef fast_speed_tag speed;
14};
15 
16template <typename T>
17void work_dispatch (const T &val, const slow_speed_tag&) {
18    std::cout << "slow" << std::endl;
19}
20 
21template <typename T>
22void work_dispatch (const T &val, const fast_speed_tag&) {
23    std::cout << "fast" << std::endl;
24}
25 
26template <typename T>
27void work (const T &val) {
28    work_dispatch(val, typename traits<T>::speed());
29}
30 
31int main () {
32    int x;
33    float y;
34 
35    work(x); // fast
36    work(y); // slow
37 
38    return 0;
39}

Another thing worth mentioning is that, the tag types are empty structs that are never used. As such, the compiler will usually be able to optimize and make them totally disappear from the compiled code – which makes this technique even more appealing.

One of the best examples of the Tag dispatch technique is the implementation of std::advance() within STL iterators. You can read more about it here.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值