模板功能专业化问题

Arn*_*rne 3 c++ enums

我正在使用模板来实现从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

APr*_*mer 5

显式专业必须在使用它们的任何地方都可见。并且由于它们是定义,因此不能在每个编译单元中重复它们。因此,在您定义枚举的头文件中,您要检查的内容是

#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中给出定义。