This is a little OT, but I decided to leave it here in case this helps someone else. I googled about the template specialization that brought me here, and although @ maxim1000's answer was correct and ultimately helped me sort out my problems, I did not think it was completely clear.
My situation is slightly different (but similar enough to leave this answer, I think) than the OP. In fact, I use a third-party library with all kinds of classes that define "status types". The heart of these types is simply enum , but all classes inherit from a common (abstract) parent and provide various helper functions, such as operator overloading and the static toString(enum type) function static toString(enum type) . Each enum status is different and unrelated. For example, one enum has fields NORMAL, DEGRADED, INOPERABLE other - AVAILBLE, PENDING, MISSING , etc. My software is responsible for managing different types of statuses for different components. This happened because I wanted to use the toString functions for these enum classes, but since they are abstract, I could not instantiate them directly. I could expand every class I wanted to use, but in the end I decided to create a template class where typename would be what specific enum status I took care of. There may probably be some debate about this solution, but I felt that it was a lot less work than expanding each abstract enum class with its own and implementing abstract functions. And of course, in my code, I just wanted to be able to call .toString(enum type) and make it print a string representation of this enum . Since all enum were completely unrelated, each of them had their own toString functions which (after some research that I studied) should have been called using template specialization. It brought me here. Below is the MCVE of what I had to do to make this work correctly. And actually my solution was slightly different from @ maxim1000.
This is a (very simplified) header file for enum . In fact, each enum class was defined in its own file. This file represents the header files that are provided to me as part of the library that I use:
// file enums.h #include <string> class Enum1 { public: enum EnumerationItem { BEARS1, BEARS2, BEARS3 }; static std::string toString(EnumerationItem e) { // code for converting e to its string representation, // omitted for brevity } }; class Enum2 { public: enum EnumerationItem { TIGERS1, TIGERS2, TIGERS3 }; static std::string toString(EnumerationItem e) { // code for converting e to its string representation, // omitted for brevity } };
adding this line is just to split the following file into another block of code:
// file TemplateExample.h
next file
// file TemplateExample.cpp #include <string> #include "enums.h" #include "TemplateExample.h" // for each enum type, I specify a different toString method, and the // correct one gets called when I call it on that type. template <> std::string TemplateExample<Enum1::EnumerationItem>::toString() { return Enum1::toString(type_); } template <> std::string TemplateExample<Enum2::EnumerationItem>::toString() { return Enum2::toString(type_); }
next file
// and finally, main.cpp
and this outputs:
BEARS1 TIGERS3
I have no idea if this is the perfect solution to solve my problem, but it worked for me. Now, no matter how many enumeration types I end up using, all I have to do is add a few lines for the toString method in the .cpp file, and I can use the already defined toString method libraries without implementing it myself and without an extension of every enum class that I want to use.