根据模板参数选择枚举类型

eml*_*lai 2 c++ enums refactoring templates c++11

我有一节课:

template <class type>
class sysbase : public base
{
 public:
  static type* Spawn(int Config = 0) { … }
  … 
};
Run Code Online (Sandbox Code Playgroud)

全局命名空间中大约有50个枚举:

enum a_config { A1, A2, … };
enum b_config { B1, B2, … };
etc.
Run Code Online (Sandbox Code Playgroud)

a,b等.(源自sysbase)将作为被传递type模板参数sysbase.

现在我想将Config参数更改为其中一个枚举类型,而不仅仅是一个普通的int来提高类型安全性,以便:

  • 什么时候type上课a,那么类型Config就是a_config
  • 什么时候type上课b,那么类型Config就是b_config
  • 等等

枚举应该优选地保留在全局命名空间中以不破坏使用例如的现有代码a::Spawn(A1).

有没有办法实现这个目标?

Naw*_*waz 6

  • 侵入式解决方案:将类中的枚举类型的typedef定义为成员,并将其作为typename type::enum_type以下内容访问:

    class a
    {
       public:
           using enum_type = a_config; //C++11 style typedef
    };
    
    //define all such classes in the same way.
    
    //lets also define a friendly template alias to access the enum type.
    template<typename T>
    using enum_type = typename T::enum_type;
    
    //then you could define Spawn as
    static type* Spawn(enum_type<T> config) { … }
    
    Run Code Online (Sandbox Code Playgroud)
  • 非侵入式解决方案:定义将类型映射到枚举并将其用作枚举的类型特征typename enum_type_<type>::type.

     template<typename>
     struct enum_type_;  //primary template (no definition)
    
     //specialize enum_type_ for each class type as:
     template<> 
     struct enum_type_<a>
     { 
        using type = a_config; 
     };
    
     //now define the alias as
     template<typename T>
     using enum_type = typename enum_type_<T>::type;
    
    //then you could define Spawn as
    static type* Spawn(enum_type<T> config) { … }
    
    Run Code Online (Sandbox Code Playgroud)

好吧,由于精心选择的别名,你的Spawn函数在两种情况下看起来都相同,即使这两个解决方案与概念观点截然不同 - 一个需要编辑类定义,另一个解决问题而不需要你编辑课程.

选择适合您情况的解决方案.

希望有所帮助.