what will you choose? virtual function, template or branch?
I had been confronted with a C++ design problem to choose between virtual function, template and branch. The three implementations are listed as follows. I eventually chose the the second implementation, which looks tricky but with best performance for a low latency design.

**virtual function implementation:**

    class Channel : public BaseChannel
    {
      void packet(...) { for (...) message(...); }
      virtual void message(...)=0;
    };
    
    class ChannelA : public Channel
    {
      struct Header {...}
      void message(...) { ... }
    }
    class ChannelB : public Channel
    {
      struct Header {...}
      void message(...) { ... }
    }
     
**template implementation:**

    template <typename TImpl>
    class Channel : public BaseChannel
    {
      void packet(...) { for (...) message(...); }
      void message(...);
    };
    
    class ChannelA : public Channel<ChannelA>
    {
      struct Header {...}
      void message(...) { ... }
    }
    class ChannelB : public Channel<ChannelB>
    {
      struct Header {...}
      void message(...) { ... }
    }
    template <typename TImpl>
    void Channel<TImpl>::message(...) { static_cast<TImpl*>(this)->message(); }

**branch implementation:**

    class Channel : public BaseChannel
    {
      void packet(...) { for (...) message(...); }
      struct HeaderA {...}
      struct HeaderB {...}
      void message(...)
      {
          if (isHeaderA(...)) messageA(...);
          else if (isHeaderB(...)) messageB(...);
      }
      void messageA(...) { ... }
      void messageB(...) { ... }
    };
     

what will you choose? virtual function, template or branch?
===

I had been confronted with a C++ design problem to choose between virtual function, template and branch. The three implementations are listed as follows. I eventually chose the the second implementation, which looks tricky but with best performance for a low latency design.

**virtual function implementation:**

    class Channel : public BaseChannel
    {
      void packet(...) { for (...) message(...); }
      virtual void message(...)=0;
    };
    
    class ChannelA : public Channel
    {
      struct Header {...}
      void message(...) { ... }
    }
    class ChannelB : public Channel
    {
      struct Header {...}
      void message(...) { ... }
    }
     
**template implementation:**

    template <typename TImpl>
    class Channel : public BaseChannel
    {
      void packet(...) { for (...) message(...); }
      void message(...);
    };
    
    class ChannelA : public Channel<ChannelA>
    {
      struct Header {...}
      void message(...) { ... }
    }
    class ChannelB : public Channel<ChannelB>
    {
      struct Header {...}
      void message(...) { ... }
    }
    template <typename TImpl>
    void Channel<TImpl>::message(...) { static_cast<TImpl*>(this)->message(); }

**branch implementation:**

    class Channel : public BaseChannel
    {
      void packet(...) { for (...) message(...); }
      struct HeaderA {...}
      struct HeaderB {...}
      void message(...)
      {
          if (isHeaderA(...)) messageA(...);
          else if (isHeaderB(...)) messageB(...);
      }
      void messageA(...) { ... }
      void messageB(...) { ... }
    };
     
