kyle Doidge
kyle Doidge

Reputation: 55

Whats the difference between "template <class T, class C>" and "template <class T> template <class C>"

Since I'm a fan of separating interface and implementation, instead of implementing a template class solely in the header, I separated it into a .h and .tpp (.tpp so that it's not compiled with *.cpp). I then included the tpp at the end of the header file just before the #endif in the header guard. Because of this choice, in the implementation (.tpp), to define a function, I would have to define each function by referring to it by its template parameters like so:

template <class T>
T MyTemplate<T>::functionName(T t){...}

However, I noticed when defining a member function with an extra template parameter, I would have to define it by referring to it using:

template <class T>
template <class C>
T MyTemplate<T>::extraTParamFunc(T t, C c){...}

instead of:

template <class T, class C>
T MyTemplate<T>::extraTParamFunc(T t, C c){...}   //no declaration matches 'T MyTemplate<T>::extraTParamFunc(T, C)'

This left me puzzled. So why is this? Whats the difference between template <class T, class C> and template <class T> template <class C>?

Also, here is an example of the .h and .tpp just in case this bears any relevance:

//MyTemplate.h
#ifndef MYTEMPLATE_H
#define MYTEMPLATE_H

template <class T>
class MyTemplate {

template <class C>
T extraTParamFunc(T t, C c);
...
}

#include "MyTemplate.tpp"
#endif //MYTEMPLATE_H

//MyTemplate.tpp
#include "MyTemplate.h"

template <class T>
template <class C>
T MyTemplate<T>::extraTParamFunc(T t, C c){...}

...

Upvotes: 1

Views: 631

Answers (1)

Martin Hierholzer
Martin Hierholzer

Reputation: 930

You can see the answer in principle in your header file:

template <class T>
class MyTemplate {

template <class C>
T extraTParamFunc(T t, C c);
...
}

The class MyTemplate is a template. Inside this template, you define another template, the function MyTemplate::extraTParamFunc. Also if you write the full function name with template parameters you can see this: MyTemplate<T>::extraTParamFunc<C>(). This is something different then MyTemplate<T,C>::extraTParamFunc() or MyTemplate::extraTParamFunc<T,C>() would be.

So you have a template inside a template, and the syntax needs to reflect this. If you make template specializations, in particular partial ones, or if you have optional template arguments, the syntax would be ambiguous if C++ would allow you to combine both templates in a single template<> line.

Upvotes: 1

Related Questions