C ++ 11 metaprogramming - the value of an enumerated number at compile time (values ​​contain spaces)

Is there a way at compile time to make sure that a given value is within the values ​​of a given enum, thus, is valid?

enum myenum { val1 = 10, val2 = 30, val3 = 45 } template <myenum t> class myClass { ... } myClass<10> a; // fails, OK myClass<val1> b; // compiles OK myClass<myenum(24)> c; //compiles, NOT OK! 

Using the second non-piggy logic parameter template would be useful there, and the value of this logical value would be set using a meta-function, which, given the value, would check that the value is within myenum values.

I looked at various enumeration-related questions, such as how to enumerate an enumeration, and it seems to be impossible.

+6
source share
5 answers
 enum myenum { val1 = 10, val2 = 30, val3 = 45 }; template<myenum e> struct is_valid_myenum { static const bool value = (e==val1 || e==val2 || e==val3); }; template<myenum t> class myClass { static_assert(is_valid_myenum<t>::value, "t must be a valid enum value"); }; myClass<10> a; // fails, OK myClass<val1> b; // compiles OK myClass<myenum(24)> c; // fails, OK 

If you really really want to avoid duplication (and are not interested in using any external tool to generate source code), you can resort to macro hacking.

 #define LIST \ ITEM(val1,10)\ ITEM(val2,30)\ ITEM(val3,45) #define ITEM(NAME,VALUE) NAME = VALUE, enum myenum { LIST }; #undef ITEM #define ITEM(NAME,VALUE) e==NAME || template<myenum e> struct is_valid_myenum { static const bool value = ( LIST false ); }; template<myenum t> class myClass { static_assert(is_valid_myenum<t>::value, "t must be a valid enum value"); }; myClass<10> a; // fails, OK myClass<val1> b; // compiles OK myClass<myenum(24)> c; // fails, OK 
+5
source

You can never stop other developers from shooting their own foot. You can never win. Just make sure your API does not make it simple .

If it takes an invalid value, discards it, and then passes it to you, it's just his problem. This is the same problem as if you were giving it a function by specifying a pointer of type T* as a parameter, but it takes some random data (of arbitrary type), discards them to T* and passes them.

How casting works: the person performing the cast is responsible for ensuring that the cast expression can be safely interpreted as a value of the type to which it ascribes.

+2
source

If you do not update all your information in the form of metaprogramming, this is not possible. However, for example, you can:

 enum myenum { val1 = 10, val2 = 30, val3 = 45 }; typedef vector_c< myenum, val1, val2, val3 > typed_myenum; typedef contains< typed_myenum, integral_c< myenum, val >::value val_found; 

Uses functionality from Boost.MPL , although the actual syntax may be slightly off.

0
source

There is no way to verify that the value is in a valid enumeration range at run time, less at compile time.

The only way to check is to check the brute force for each value. Something like that:

 enum lala { A = 10, B = 20, C = 30 }; template< int value > struct T { static_assert( (value == A) || (value == B ) || (value == C), "wrong value" ); }; int main() { T< 10 > t10; T< 20 > t20; T< 25 > t25; T< 30 > t30; (void)t10;(void)t20;(void)t25;(void)t30; } 
0
source

If the enumeration name is not important to you, perhaps you can just transfer it to an array, for example:

 const int myenum[]={10,30,45} 

then use the index to refer to them from myenum.

 template<unsigned int t> class myClass { static_assert(t < sizeof(myenum)/sizeof(int), "t must be a valid enum index"); int val=myenum[t]; ... }; 
0
source

Source: https://habr.com/ru/post/918791/


All Articles