There is this code:
#include <iostream>
#include <string>
#include <typeinfo>
// template class
template <class U, class X, class T>
class Klasa{
public:
template <class Z>
void Method(){
}
};
// partial class specialization
template <class U>
class Klasa<U, int, U>
{
public:
// template method
template <class Z>
void Method(){
}
};
// error occurs for that!
template <class U>
template <>
void Klasa<U, int, U>::Method<int>(){
}
int main()
{
Klasa<float, int, float> object;
object.Method<float>();
return 0;
}
Compilation error:
error: invalid explicit specialization before ‘>’ token
error: enclosing class templates are not explicitly specialized
error: template-id ‘Method<int>’ for ‘void Klasa<U, int, U>::Method()’ does not match any template declaration
I try to do specialization for method
void Klasa<U, int, U>::Method<int>
, however compiler doesn’t accept it. How to write specialization for this method?
Don’t ask me for exact quotes but according to David Vandevoorde this can’t be done. The rationale is that this is essentially a partial specialization of a function template and there is no such thing. One reason to disallow this is that it is unclear what should happen with this specialization if there is a further specialization of the class: is the function specialization inherited or is it not inherited?
Obviously, stating that this can’t be done isn’t really a lot of help. What can be done instead? A simple approach would be to delegate the implementation to an overloaded private implementation which takes e.g. a pointer argument to disambiguate between the various types. I realize that the whole point probably is to avoid the use of an extra argument, even if it is only used internally. Another possible approach could be the use of fully specialized base class: member function templates of this can be explicitly specialized.