Reputation: 387
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
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
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