Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
182 views
in Technique[技术] by (71.8m points)

c++ - Template metaprogram converting type to unique number

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, like below:

int myInt = TypeInt<AClass>::value;

Where value should be a compile time constant, which in turn may be used further in meta programs.

I want to know if this is at all possible, and in that case how. Because although I have learned much about exploring this subject I still have failed to come up with an answer.

(P.S. A yes/no answer is much more gratifying than a c++ solution that doesn't use metaprogramming, as this is the domain that I am exploring)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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<AClass> { enum { result = 1 }; };
template<> struct type2int<BClass> { enum { result = 2 }; };
template<> struct type2int<CClass> { enum { result = 3 }; };

const int i = type2int<T>::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<AClass, BClass, CClass> the_type_list;

// your meta function
template< typename T >
struct type2int
{
   enum { result = index_of<T, the_type_list>::result };
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...