I have an extendable collection of classes that have approximately the same interface, that each have a different static constant for serialization purposes. Consider:
class A {
constexpr static int value = 0;
};
class B {
constexpr static int value = 1;
};
Now, I'd like to do a reverse mapping from value to the class itself. I can do:
template <int value> struct type_for_value { };
template <> struct type_for_value<0> { using type = A; };
template <> struct type_for_value<1> { using type = B; };
This works, however, every time I add a class to the collection (say class C), I have to add another template specialization. I also have other functions that use the entire collection of classes, such as:
constexpr auto for_each_class(auto const& func) {
return func.template operator()<A, B>;
}
Here I'd also need to add C to the parameter pack.
Is there any way to define the collection of classes once (maybe a macro, but preferably using something better typed like a single parameter pack), such that the template specializations are automatically generated at compile time, and that I can also use in the for_each_class
function?
I tried to create a single struct with a parameter pack, like this:
template <typename... T>
struct all_classes_impl {
constexpr static auto for_each_class(auto const& func) {
return func.template operator()<T...>();
}
template <int value>
struct type_for_value { };
template <>
struct type_for_value<T::type> {
using type = T;
}...;
}
using all_classes = all_classes_impl<A, B>;
constexpr auto for_each_class = &all_classes::for_each_class;
But this doesn't work for the template specializations, and aliasing the for_each_class
also does not work in this way.