这不是标签调度。正如您在问题中正确所说,如果您使用了某些编译时特征A
and B
区分两者,然后使用它在两个不同的重载之间进行选择。
标签调度的一个很好的例子是std::advance http://en.cppreference.com/w/cpp/iterator/advance通常被实施。该函数的签名是
template< class InputIt, class Distance >
void advance( InputIt& it, Distance n );
it
可以进阶n
如果满足 RandomAccessIterator 的要求,则在单个操作中定位。对于较小的迭代器,我们必须前进it
循环中。因此,实现可能会执行类似于以下内容的操作:
namespace detail
{
template<class InputIt, class Distance>
void advance(InputIt& it, Distance n, std::random_access_iterator_tag)
{
it += n;
}
template<class InputIt, class Distance>
void advance(InputIt& it, Distance n, std::bidirectional_iterator_tag)
{
if(n < 0) {
while(n++) --it;
} else {
while(n--) ++it;
}
}
template<class InputIt, class Distance>
void advance(InputIt& it, Distance n, std::input_iterator_tag)
{
assert(n >= 0);
while(n--) ++it;
}
}
template< class InputIt, class Distance >
void advance( InputIt& it, Distance n )
{
detail::advance(it, n,
typename std::iterator_traits<InputIt>::iterator_category());
}
我不知道你正在做的事情的具体名称。这只是一个如何遵循的示例DRY https://en.wikipedia.org/wiki/Don%27t_repeat_yourself原则。
If bar
举了一个例子A
and B
作为一个论点,那么我会以不同的方式实现它。而不是制作bar
一个函数模板,然后提供专业化,我会让重载解析为我完成这项工作。
void bar(A const&) { ... }
void bar(B const&) { ... }
但由于情况并非如此,因此提供明确的专业化似乎是做到这一点的正确方法。