这与正题有些偏离,但我认为如果能帮助到其他人,还是留在这里吧。我在搜索模板特化时来到了这里,虽然@maxim1000的回答是正确的,最终也帮助我解决了问题,但我认为它并不十分清晰易懂。
我的情况有点不同(但足够类似,我认为可以留下这个答案)。基本上,我正在使用一个第三方库,其中包含各种定义“状态类型”的类。这些类型的核心只是 enum
,但是这些类都继承自一个共同的(抽象)父级,并提供不同的实用函数,例如运算符重载和 static toString(enum type)
函数。每个状态 enum
都彼此不同且无关。例如,一个 enum
具有字段 NORMAL,DEGRADED,INOPERABLE
,另一个则具有 AVAILBLE,PENDING,MISSING
等。我的软件负责管理不同组件的不同类型的状态。我想利用这些 enum
类的 toString
函数,但由于它们是抽象的,所以我无法直接实例化它们。我可以扩展我想要使用的每个类,但最终我决定创建一个 template
类,其中 typename
将是我关心的任何具体状态的 enum
。可能会对这个决定产生争议,但我觉得这比扩展每个抽象 enum
类与我自己的自定义类并实现抽象函数要少得多。当然,在我的代码中,我只想能够调用 .toString(enum type)
并打印该 enum
的字符串表示形式。由于所有的 enum
都是完全不相关的,它们各自都有自己的 toString
函数(经过一些研究后我了解到)必须使用模板特化来调用。这就导致了我在这里。以下是我必须执行的MCVE,以便使其正常工作。实际上,我的解决方案与@maxim1000的略有不同。
这是一个(大大简化的)枚举头文件。实际上,每个枚举类都在自己的文件中定义。该文件代表了作为我使用的库的一部分提供给我的头文件:
#include <string>
class Enum1
{
public:
enum EnumerationItem
{
BEARS1,
BEARS2,
BEARS3
};
static std::string toString(EnumerationItem e)
{
}
};
class Enum2
{
public:
enum EnumerationItem
{
TIGERS1,
TIGERS2,
TIGERS3
};
static std::string toString(EnumerationItem e)
{
}
};
添加这行代码只是为了将下一个文件分隔成不同的代码块:
#include <string>
template <typename T>
class TemplateExample
{
public:
TemplateExample(T t);
virtual ~TemplateExample();
std::string toString();
private:
T type_;
};
template <typename T>
TemplateExample<T>::TemplateExample(T t)
: type_(t)
{
}
template <typename T>
TemplateExample<T>::~TemplateExample()
{
}
下一个文件
#include <string>
#include "enums.h"
#include "TemplateExample.h"
template <>
std::string TemplateExample<Enum1::EnumerationItem>::toString()
{
return Enum1::toString(type_);
}
template <>
std::string TemplateExample<Enum2::EnumerationItem>::toString()
{
return Enum2::toString(type_);
}
下一个文件
#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
我不确定这是否是解决我的问题的理想解决方案,但对我起作用了。现在,无论我使用多少枚举类型,我只需在 .cpp 文件中添加几行 toString
方法代码,就可以使用已定义的库中的 toString
方法,而无需自己实现它或扩展每个要使用的 enum
类。