c++ - Composing std::integral_constant values -


consider code

#include <iostream> #include <type_traits>  enum thing {thing0, thing1, thing2, numthings}; enum object {object0, object1, object2, numobjects};  template <thing> struct thingvalue;  template <> struct thingvalue<thing0> : std::integral_constant<int, 5> {}; template <> struct thingvalue<thing1> : std::integral_constant<int, 2> {}; template <> struct thingvalue<thing2> : std::integral_constant<int, 12> {};  template <object> struct objectvalue;  template <> struct objectvalue<object0> : std::integral_constant<thing, thing2> {}; template <> struct objectvalue<object1> : std::integral_constant<thing, thing0> {}; template <> struct objectvalue<object2> : std::integral_constant<thing, thing1> {};  int main() {     std::cout << thingvalue<objectvalue<object0>::value>::value << '\n';  // 12 } 

i'm trying define, composevalues<t, value, pack...> above in main() can written composevalues<object, object0, thingvalue, objectvalue>::value. can extended number of such compositions. not absolutely vital thing do, i'd figure nice little exercise define such thing. i'm having difficulty syntax:

template <typename t, t value, template <typename> class...> struct composevalues;  template <typename t, t value, template <typename> class first, template <typename> class... rest> struct composevalues<t, value, first, rest...> {     static auto value = first<typename composevalues<t, value, rest...>::value>::value; };  template <typename t, t value, template <t> class last> struct composevalues<t, value, last> : std::integral_constant<t, last<value>::value> {};  // won't compile. 

is possible i'm trying do?

the issue having can't mix template templates take different non-type arguments. in example, means objectvalue , thingvalue cannot bind template <typename> class....

a way fix encode enums in type kind of template can hold both of them indiscriminately. possible way treat enums ints , let user worry passing in reasonable types.

first create wrappers around current types:

template <typename> struct thingvaluewrapper; template <int i> struct thingvaluewrapper<std::integral_constant<int,i>>      : thingvalue<static_cast<thing>(i)> {};  template <typename> struct objectvaluewrapper; template <int i> struct objectvaluewrapper<std::integral_constant<int, i>>      : objectvalue<static_cast<object>(i)> {}; 

then can pretty similar had:

template <typename t, t value, template <typename> class...> struct composevalues;  template <typename t, t value,            template <typename> class first,            template <typename> class... rest> struct composevalues<t, value, first, rest...>     : std::integral_constant<int,                              first<typename composevalues<t, value, rest...>::type>::value> {};  template <typename t, t value> struct composevalues<t, value> : std::integral_constant<int, static_cast<int>(value)> {}; 

the difference original use-case need use our wrappers instead of original enum traits:

composevalues<object, object0, thingvaluewrapper, objectvaluewrapper>::value 

Comments

Popular posts from this blog

powershell Start-Process exit code -1073741502 when used with Credential from a windows service environment -

twig - Using Twigbridge in a Laravel 5.1 Package -

c# - LINQ join Entities from HashSet's, Join vs Dictionary vs HashSet performance -