I am encountering some issues when I try to force template specialization with an incomplete (partially specified) templated type.
Let's consider this oversimplified example: I have a template function declaration for which I provide forced specification for some common types in the corresponding C++ file.
in .h file:
template <class T>
void doSomething(const T &value);
in cpp file:
// force template specializations with various types
template <>
void doSomething<float>(const float &value)
{
// actual code specialization for type float, es:
printf("%.3f", value);
}
...
and for example, I want to do the same specialization for glm vector (from OpenGL Mathematics library), which is templated on the number of components and on the data type of its components (and also on precision, that I will skip in this example for clarity).
What I would like to avoid is to explicitly write the actual specialization for all possible values of N (leading to code repetition, since it is basically the same loop but with different number of iterations), as shown here:
template <>
void doSomething<glm::vec<2, float>>(const glm::vec<2, float> &value)
{
printf("{");
printf("%.3f", value[0]);
for (int i = 1; i< 2 ++i)
printf(", %.3f", value[i]);
printf("}");
}
template <>
void doSomething<glm::vec<3, float>>(const glm::vec<3, float> &value)
{
printf("{");
printf("%.3f", value[0]);
for (int i = 1; i< 3 ++i)
printf(", %.3f", value[i]);
printf("}");
}
template <>
void doSomething<glm::vec<4, float>>(const glm::vec<4, float> &value)
{
printf("{");
printf("%.3f", value[0]);
for (int i = 1; i< 4 ++i)
printf(", %.3f", value[i]);
printf("}");
}
What I would like to do is writing something like this:
template <glm::length_t N>
void doSomething<glm::vec<N, float>>(const glm::vec<N, float> &value)
{
printf("{");
printf("%.3f", value[0]);
for (int i = 1; i< N ++i)
printf(", %.3f", value[i]);
printf("}");
}
// force full template specializations
template void doSomething<glm::vec<2, float>>(const glm::vec<2, float> &value);
template void doSomething<glm::vec<3, float>>(const glm::vec<3, float> &value);
template void doSomething<glm::vec<4, float>>(const glm::vec<4, float> &value);
but this solution arises the following compilation error: "illegal use of explicit template arguments"
I have read that "Function partial specialization" is not allowed in C++, is this limitation still valid in modern standards C++ (14/17/20)? Is this the cause of the issue or maybe I am missing something? Thank you all in advance.
Partial Function Specialization is not allowed. However, you can avoid explicitly writing the code for all possible values of N by using Function Overloading. The example below is based on your code, but I've replaced
glm::vec<>withstd::array<>since they are similar. Also, I only used a.Cfile for convenience.Here is the output: