Is this "Tag Dispatching"?

c++, c++11, template-meta-programming, templates

Solution

This isn't tag dispatching. As you rightly said in your question, that'd be if you used some compile time trait of `A` and `B` to distinguish between the two, and then use that to select between two different overloads.

An good example of tag dispatch would be how `std::advance` is typically implemented. The function's signature is

template< class InputIt, class Distance >
void advance( InputIt& it, Distance n );

`it` can be advanced `n` positions in a single operation if it meets the requirements of RandomAccessIterator. For lesser iterators we must advance `it` in a loop. So an implementation would probably do something similar to the following:

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());
}

I don't know of any specific name for what you're doing. It's just an example of how one would follow the DRY principle.

If `bar` took an instance of `A` and `B` as an argument, then I'd implement this differently. Instead of making `bar` a function template, and then providing specializations, I'd let overload resolution do the job for me.

void bar(A const&) { ... }
void bar(B const&) { ... }

But since that's not the case, providing explicit specializations seems the right way to do this.

Problem

Say I have some code: ``` void barA() { } void barB() { } void fooA() { // Duplicate code... barA(); // More duplicate code... } void fooB() { // Duplicate code... barB(); // More duplicate code... } int main() { fooA(); fooB(); } ``` And I want to remove the duplicate code between `fooA` and `fooB` I could use a number of dynamic techniques such as passing in a bool parameter, passing a function pointer or virtual methods but if I wanted a compile time technique I could do something like this: ``` struct A { }; struct B { }; template<typename Tag> void bar(); template<> void bar<A>() { } template<> void bar<B>() { } template<typename Tag> void foo() { // Duplicate code bar<Tag>(); // More duplicate code } int main() { foo<A>(); foo<B>(); } ``` where I have introduced two empty "Tag" classes to indicate which `bar` to use and templated `foo` and `bar` based on the tag class. This seems to do the trick. Questions: - Does this technique have a name? is this an example of "Tag dispatching"? From what I read about Tag dispatching it is slightly different and involves function overloading with a tag parameter. A tag that may have come from a typedef in a trait class. - Is there a more idomatic compile-time technique of achieving the same thing? Edit: Another possibility would be to use function overloading of `bar` instead of template specialization and pass the tag class as a parameter: ``` struct A { }; struct B { }; void bar(A) { } void bar(B) { } template<typename Tag> void foo() { // Duplicate code bar(Tag()); // More duplicate code } int main() { foo<A>(); foo<B>(); } ```

Original source

Related problems