Template class inside class template in c++
Asked Answered
C

6

6

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.

Cannot answered 7/7, 2009 at 7:24 Comment(3)
Post getMessageSender function code here.Foregone
food does not have a return type, that's your problemRaseda
You are all correct in your observations. However, those were typos. The actual problem was the lack of the 'template' keyword as answered by FaisalCannot
C
11

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.

Consortium answered 7/7, 2009 at 7:33 Comment(2)
On which compiler do you need to do that?Raseda
@Edouard - The standard requires the 'template' prefix only when accessing member templates from an identifier that depends on a template parameter - most compilers should get this right since this has been part of the standard since '98 - in '03 they modified the rules for the sake of simplicity so that you could use it on all member template accesses - and asides from the EDG compilers (that do mostly get this right), i haven't checked it on any of the other compilers - please let me know if you have.Consortium
I
2

Add the keyword template between -> and the name of the template method:

t_->template getMessageSender<MessageType>();
Intinction answered 7/7, 2009 at 7:41 Comment(0)
C
0

Likely, MessageType isn't known at that point. Are you missing an include, a namespace resolution or a declaration?

if tht's not it, how is getMessageSender declared, and how is MessageType?

Generally, in C++ it is not a problem if T is not known at that point (well... it's complicated, but still).

Also, the error message usually contains the type for which it is tried to be insantiated. Try to post the full error message at least.

Cichlid answered 7/7, 2009 at 7:32 Comment(0)
M
0

Do you have other similar calls to methods like getMessageSender that are templatized?

t_->getMessageSender<MessageType>();
Mair answered 7/7, 2009 at 7:33 Comment(0)
T
0

It's just the return type of your function that's missing. The t_ member is fully defined.

A specialization of a template is a 'special' version your implement for specific template arguments. An example: std::vector is the specialized version of the generic std::vector.

A partial specialization is an implementation of your generic code where not all template arguments are provided.

Trinitytrinket answered 7/7, 2009 at 9:10 Comment(0)
D
0

This works fine on Visual Studio 2010 compiler.

class One
{
public:
    void newFoo() ;
    template < class T > void foo()
    {
        T obj ;  // obj is dependent on template parameter
        obj.newFoo() ;  // and this works
    }
}

Just to keep the answer updated !!!

Dispense answered 5/1, 2011 at 3:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.