23 September 2023

C++ 核心指南目录

“Use tag dispatch to provide alternative implementations of a function”

理由

  • 模板定义了通用接口
  • 标签分派机制允许我们基于参数的特定属性选择不同的实现
  • 性能更好

例子

这是 std::copy 的简化版本。

struct pod_tag {};
struct non_pod_tag {};

// T is not "plain old data"
template<class T> struct copy_trait { using tag = non_pod_tag; };

// int is "plain old data"
template<> struct copy_trait<int> { using tag = pod_tag; };

template<class Iter>
Out copy_helper(Iter first, Iter last, Iter out, pod_tag)
{
    // use memmove
}

template<class Iter>
Out copy_helper(Iter first, Iter last, Iter out, non_pod_tag)
{
    // use loop calling copy constructors
}

template<class Iter>
Out copy(Iter first, Iter last, Iter out)
{
    return copy_helper(first, last, out, typename copy_trait<Value_type<Iter>>::tag{})
}

void use(vector<int>& vi, vector<int>& vi2,
         vector<string>& vs, vector<string>& vs2)
{
    copy(vi.begin(), vi.end(), vi2.begin()); // uses memmove
    copy(vs.begin(), vs.end(), vs2.begin()); // uses a loop calling copy constructors
}

这是一个通用的、强大的编译时算法选择技术。

注意

concept 大规模应用的时候,可以直接选择不同实现方式:

template<class Iter>
    requires Pod<Value_type<Iter>>
Out copy_helper(In, first, In last, Out out)
{
    // use memmove
}

template<class Iter>
Out copy_helper(In, first, In last, Out out)
{
    // use loop calling copy constructors
}