Search code examples
c++templatesspecializationclass-template

Template class inside class template in c++


noob here still experimenting with templates. Trying to write a message processing class template

template <typename T> class MessageProcessor {

  //constructor, destructor defined
  //Code using t_ and other functions
foo( void ) {

//More code in a perfectly fine method
}
  private:  T *t_

};

All defined in a header file. I've built and tested my class and all is well. Now, I'm trying to do this:

template <typename T> class MessageProcesor {

  //Same stuff as before

foo(void) {
//Same code as before in foo, but one new line:
  t_->getMessageSender<MessageType>();

}

private: T *t_;
};

However, this line gives me an error of bad expression-type before '>' token.

I've added the necessary header files to define what a MessageType is. I've used this function many time before, just not in this context.

I suspect that the compiler doesn't like the fact that the template function is fully defined (specialized?) within an undefined class template (unspecialized?). I'm not fully grokking what makes a template 'specialized'. Most explanations center on the concepts of 'full' or 'partial', but not what makes it specialized in the first place.

Apologies if you'd like to see more code. I have no internet access at work and that's where I'm doing this, so I have to put everything into my mental 'scratchpad' and bring it home.


Solution

  • Your member function 'foo' needs a return type and you need to use the keyword 'template' when you use member templates in dependent expressions (expressions whose meanings rely directly or indirectly on a generic template parameter)

    t_->template getMessageSender<MessageType>();  // ok
    t_->getMessageSender<MessageType>(); // not ok
    

    Perhaps this example will help you appreciate when a member template needs to be prefixed by the 'template' keyword [Note: in the interest of symmetry you may always use the 'template' prefix on member templates, but it is optional when used on a non-dependent expression.

    struct MyType
    {  
      template<class T> void foo() { }
    };
    
    template<class U>
    struct S
    {
      template<class T>
      void bar()
      {
        MyType mt;  // non-dependent on any template parameter
        mt.template foo<int>(); // ok
        mt.foo<int>();  // also ok
    
        // 't' is dependent on template parameter T
        T t;
        t.template foo<int>();    // ok
        t.foo<int>(); // not ok
    
        S<T> st; // 'st' is dependent on template parameter T
        st.template foo<int>();    // ok
        st.foo<int>(); // not ok
    
    
        S<MyType> s;  // non-dependent on any template parameter
        s.bar<int>(); // ok
        s.template bar<int>(); // also ok
    
      }
    
    };
    

    Hope that helps.