When I try to specialize a public member function template within the class definition/declaration:
#include <iostream>
class surfaceMesh
{
public:
// Uncomment for Version 0 and 1
class AREA_AVERAGE {};
class ANGLE_AVERAGE {};
template<class Average>
void vertexNormals() {}
// Uncomment: Version 0
//template<>
//void vertexNormals<AREA_AVERAGE> ()
//{
//std::cout << "AREA_AVERAGE" << std::endl;
//}
//template<>
//void vertexNormals<ANGLE_AVERAGE> ()
//{
//std::cout << "ANGLE_AVERAGE" << std::endl;
//}
};
// Uncommend for version 1
template<>
void surfaceMesh::vertexNormals<surfaceMesh::AREA_AVERAGE> ()
{
std::cout << "AREA_AVERAGE" << std::endl;
};
template<>
void surfaceMesh::vertexNormals<surfaceMesh::ANGLE_AVERAGE> ()
{
std::cout << "ANGLE_AVERAGE" << std::endl;
};
int main()
{
surfaceMesh m;
m.vertexNormals<surfaceMesh::AREA_AVERAGE>();
m.vertexNormals<surfaceMesh::ANGLE_AVERAGE>();
return 0;
}
For Version 0, the error is:
main.cpp:19: error: template-id ‘vertexNormals<mesh::AREA_AVERAGE>’ in declaration of primary template
main.cpp:24: error: explicit specialization in non-namespace scope ‘class mesh’
main.cpp:25: error: template-id ‘vertexNormals<mesh::ANGLE_AVERAGE>’ in declaration of primary template
main.cpp:25: error: ‘void mesh::vertexNormals()’ cannot be overloaded
main.cpp:19: error: with ‘void mesh::vertexNormals()’
Version 1 compiles and runs. Of course, usually I am separating the class declaration and definition, but I would really like to know why this happens.
Also, is this a good way to specialize an interface? The other option would be to overload the function vertexNormals to take an object of AREA_AVERAGE or ANGLE_AVERAGE, but this is just a type telling me which kind of function I will be using, it is not supposed to be instantiated, so using templates ‘feels’ like a right choice.
Because that is the rule laid down by the C++ Standard.
As for what you want, a better approach is to use function overload rather than function specialization as:
The type of the expression
static_cast<Average*>(0)helps the compiler to choose the correct overload.