Template metaprogram converting type to unique number

后端 未结 9 966
小鲜肉
小鲜肉 2020-12-03 03:37

I just started playing with metaprogramming and I am working on different tasks just to explore the domain. One of these was to generate a unique integer and map it to type,

9条回答
  •  醉话见心
    2020-12-03 04:39

    In principle, this is possible, although the solution probably isn't what you're looking for.

    In short, you need to provide an explicit mapping from the types to the integer values, with one entry for each possible type:

    template< typename T >
    struct type2int
    {
       // enum { result = 0 }; // do this if you want a fallback value
    };
    
    template<> struct type2int { enum { result = 1 }; };
    template<> struct type2int { enum { result = 2 }; };
    template<> struct type2int { enum { result = 3 }; };
    
    const int i = type2int::result;
    

    If you don't supply the fallback implementation in the base template, this will fail for unknown types if T, otherwise it would return the fallback value.

    Depending on your context, there might be other possibilities, too. For example, you could define those numbers within within the types themselves:

    class AClass {
      public:
        enum { inta_val = 1 };
      // ...
    };
    
    class BClass {
      public:
        enum { inta_val = 2 };
      // ...
    };
    
    // ... 
    
    template< typename T >
    struct type2int
    {
       enum { result = T::int_val }; // will fail for types without int_val
    };
    

    If you give more context, there might be other solutions, too.

    Edit:

    Actually there isn't any more context to it. I was looking into if it actually was possible, but without assigning the numbers itself.

    I think Mike's idea of ordering is a good way to do this (again, for a fixed set of types) without having to explicitly assign numbers: they're implicitly given by the ordering. However, I think that this would be easier by using a type list. The index of any type in the list would be its number. I think something like the following might do:

    // basic type list manipulation stuff
    template< typename T1, typename T2, typename T3...>
    struct type_list;
    
    // meta function, List is assumed to be some instance of type_list
    template< typename T, class List >
    struct index_of {
      enum { result = /* find index of T in List */ };
    };
    
    // the list of types you support
    typedef type_list the_type_list;
    
    // your meta function
    template< typename T >
    struct type2int
    {
       enum { result = index_of::result };
    };
    

提交回复
热议问题