这有点旧,但是我想我把它留在这里,以防它对别人有帮助。我一直在关注模板专业化,这导致了我的到来,尽管@ maxim1000的答案是正确的,并最终帮助我弄清了我的问题,但我认为这并不是很清楚。
我的情况与OP略有不同(但我想足以回答这个问题)。基本上,我使用的是第三方库,其中包含定义“状态类型”的所有不同种类的类。这些类型的核心只是enum
s,但是所有类都继承自公共(抽象)父级,并提供不同的实用程序功能,例如运算符重载和static toString(enum type)
功能。每种状态enum
互不相同且互不相关。例如,一个enum
拥有字段NORMAL, DEGRADED, INOPERABLE
,另一个拥有字段,AVAILBLE, PENDING, MISSING
等等。我的软件负责管理不同组件的不同类型的状态。结果是我想利用这些toString
功能enum
类,但是由于它们是抽象的,因此无法直接实例化它们。我本可以扩展我想使用的每个类,但最终我决定创建一个template
类,typename
无论enum
我关心的具体状况如何。也许可以就该决定进行一些辩论,但是我觉得这比enum
用我自己的自定义对象扩展每个抽象类并实现抽象功能要少得多。当然,在我的代码中,我只想能够调用.toString(enum type)
并打印出该字符串的表示形式enum
。由于所有enum
s都完全不相关,因此它们每个人都有自己的toString
函数(在我学习了一些研究之后)必须使用模板专门化来调用。那把我引到了这里。以下是我为了使此工作正常进行所必须执行的操作的MCVE。实际上,我的解决方案与@ maxim1000的解决方案有点不同。
这是的头文件(已大大简化)enum
。实际上,每个enum
类都在其自己的文件中定义。此文件表示作为我正在使用的库的一部分提供给我的头文件:
// 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
}
};
添加此行只是为了将下一个文件分成不同的代码块:
// file TemplateExample.h
#include <string>
template <typename T>
class TemplateExample
{
public:
TemplateExample(T t);
virtual ~TemplateExample();
// this is the function I was most concerned about. Unlike @maxim1000's
// answer where (s)he declared it outside the class with full template
// parameters, I was able to keep mine declared in the class just like
// this
std::string toString();
private:
T type_;
};
template <typename T>
TemplateExample<T>::TemplateExample(T t)
: type_(t)
{
}
template <typename T>
TemplateExample<T>::~TemplateExample()
{
}
下一个档案
// 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_);
}
下一个档案
// and finally, main.cpp
#include <iostream>
#include "TemplateExample.h"
#include "enums.h"
int main()
{
TemplateExample<Enum1::EnumerationItem> t1(Enum1::EnumerationItem::BEARS1);
TemplateExample<Enum2::EnumerationItem> t2(Enum2::EnumerationItem::TIGERS3);
std::cout << t1.toString() << std::endl;
std::cout << t2.toString() << std::endl;
return 0;
}
并输出:
BEARS1
TIGERS3
不知道这是否是解决我的问题的理想解决方案,但这对我有用。现在,无论我最终使用了多少枚举类型,我要做的就是toString
在.cpp文件中为该方法添加几行,并且我可以使用已经定义的toString
方法库而无需自己实现并且无需扩展每个方法enum
我要使用的课程。