我正在使用模板来实现从int到enum的范围检查转换。看起来像这样:
template<typename E>
E enum_cast(const int &source);
Run Code Online (Sandbox Code Playgroud)
模板功能或多或少地位于项目的根目录中。当定义一个新的枚举时,可以像这样从配置文件中分配值:
enum ConfigEnum {
ConfigEnumOption1 = 'A'
, ConfigEnumOption2 = 'B'
, ConfigEnumInvalid };
ConfigEnum option = XmlNode.iAttribute("option");
Run Code Online (Sandbox Code Playgroud)
我在使用此枚举的模块的.cpp文件中为此特定枚举类型定义了模板专用化。
template<>
ConfigEnum enum_cast(const int &source) {
switch(source) {
case ConfigEnumOption1 : return ConfigEnumOption1;
case ConfigEnumOption2 : return ConfigEnumOption2;
default return ConfigEnumInvalid;
}
Run Code Online (Sandbox Code Playgroud)
现在,将int分配给枚举变为:
ConfigEnum option = enum_cast<ConfigEnum>(XmlNode.iAttribute("option"));
Run Code Online (Sandbox Code Playgroud)
这样可以确保枚举始终在有效范围内。请注意,我没有始终控制这些枚举,因此这似乎是一个合理且易于配置的解决方案。
无论如何,这一切都很好(尽管我不能保证这里给出的所有代码都是正确的,因为我现在只是从内存中调用它)
问题源于这样一个事实,即在将in分配给枚举时可能不希望在代码库中使用此“ enum_cast”构造。毕竟,这可以通过简单的搜索和替换操作来实施。当然,我不想为所有枚举定义这些专业化知识,而只是为那些目前需要范围检查的人定义。我宁愿在需要时为枚举类型添加模板专业化,而在未定义专业化时使用赋值运算符。
从而:
InternalEnum internal = enum_cast<InternalEnum>(internal_integer);
Run Code Online (Sandbox Code Playgroud)
有效地调用internal = internal_integer。我认为我需要告诉编译器对所有没有专门化的枚举类型使用某种“默认”实现。
我的第一个选择是给原始模板函数一个这样的实现:
template<typename E>
E enum_cast(const int &source) {
E copy = source;
return copy;
};
Run Code Online (Sandbox Code Playgroud)
不幸的是,现在总是调用它,而不是深入到项目目录树中的.cpp文件中给出的专业化名称。
有什么想法吗?
在此先感谢Arne
显式专业必须在使用它们的任何地方都可见。并且由于它们是定义,因此不能在每个编译单元中重复它们。因此,在您定义枚举的头文件中,您要检查的内容是
#include "enum_cast.h"
enum Foo { Foo_A, Foo_B, Foo_C };
template<> Foo enum_cast<Foo>(int source);
Run Code Online (Sandbox Code Playgroud)
并在相应的.cpp中给出定义。