I'm going to start with how I imagine using the code I'd like to create. It doesn't have to be exactly like this but it's a good example of what I mean by "concise" in the title. In my case it's mapping of a type to a related enumeration value.
struct bar : foo<bar, foo_type::bar> { /* ... */ };
// \_/ \___________/
// ^ Type ^ Value
What this should ideally do is an automatic registration of a bidirectional mapping between the first template parameter of foo
, a type, and second, a value, just with the inheritance syntax and proper template parameters, so that I can later do what's in the example below.
foo_type value = to_value<bar>; // Should be foo_type::bar
using type = to_type<foo_type::bar>; // Should be bar
I know I could manually write two template specializations per type-value pair to do this but I'm wondering if it could be less tedious than that without using macros.
What I tried already is...
- Specializing template aliases to write less code to generate specializations. Apparently not possible in the current C++ version (17/20).
- Specializing inherited template member types.
struct foo_base
{
template<typename T>
struct to_value
{};
template<foo_type E>
struct to_type
{};
};
template<typename T, foo_type E>
struct foo : public foo_base
{
template<>
struct to_value<T>
{
static constexpr auto value = E;
};
template<>
struct to_type<E>
{
using type = T;
};
};
It would then be used similarily to what I presented at the beginning.
foo_type value = foo_base::to_value<bar>::value; // Should be foo_type::bar
using type = foo_base::to_type<foo_type::bar>::type; // Should be bar
But it fails with errors below on MSVC.
explicit specialization; 'foo_base::to_value' has already been instantiated
'foo_base::to_value': cannot specialize template in current scope
I feel like it might not be doable without explicit manual specializations, but C++17 allows a lot of surprising template based hacks, so want to confirm with more experienced people before I drop the idea.
foo_type
? – Bacteriostasisto_value
is easy: just make it look insidebar
(you can add arbitrary symbols here in thefoo
wrapper). – Toribar
though. – Naphthylvalue
is defined as a static member of templatedfoo
. – Naphthyl