Hélène
Hélène

Reputation: 387

Difference between a template with two parameters and two declarations of templates with one parameter each

What would be the difference between the next two declarations:

template<class T, class functor>
methodReturnType className::methodName(functor f)

and:

template<class T>
template<class functor>
methodReturnType className::methodName(functor f)

I was trying to write a method that would work with a functor arg. The second declaration allowed me to avoid to declare the whole class as a template of both T and functor. I wanted to have a template class className of only one parameter T, but inside that class, a method had another parameter functor, while not declaring the whole class as a template of two parameters. It worked, but I didn't thoroughly understand it.

Upvotes: 7

Views: 308

Answers (2)

James Kanze
James Kanze

Reputation: 153929

The first is a (non-template) member function of the class template template< typename T, typename functor > class className. The second is a member function template of the class template template <typename T> class className, e.g.:

First:

template <typename T, class Functor >
class ClassName
{
ReturnType functionName( Functor f );
};

Second:

template <typename T>
class ClassName
{
template <typename Functor>
ReturnType functionName( Functor f );
};

You say you didn't thoroughly understand it, but you seem to have grasped the essential: in the second case, the class template has only one parameter, but even after instantiation (definition of type T), the member function remains a template, which can be instantiated over many different types. And since it is a function template, template argument deduction applies, so you don't have to specify the type; the compiler will figure it out for itself when you call the function.

Upvotes: 4

ForEveR
ForEveR

Reputation: 55887

Second variant is right for your case by language rules.

n3376 14.5.2/1

A member template of a class template that is defined outside of its class template definition shall be specified with the template-parameters of the class template followed by the template-parameters of the member template.

[ Example:

template<class T> struct string {
template<class T2> int compare(const T2&);
template<class T2> string(const string<T2>& s) { /∗ ... ∗/ }
};
template<class T> template<class T2> int string<T>::compare(const T2& s) {
}

— end example ]

Upvotes: 3

Related Questions