I have no hope that what I'd like to achieve is possible in C++, but maybe I'm wrong since my previous question about bidirectional static mapping got an unlikely answer.
I have a set of certain types, an enumeration with keys representing the types, and a template handle type that accepts mentioned types as template parameters.
struct foo {};
struct bar {};
enum class types { foo, bar };
template<typename T>
struct qux {};
I'd like to be able to map types::foo
to foo
at runtime. Most of the time foo
would be used as the template parameter of qux
, so mapping of types::foo
to qux<foo>
is fine too but I feel that if one is possible, then the other is too.
I'm mentioning this because it's important to note that qux
is a simple handle-like type that only consists of an index and is passed around by value and there are a lot of template functions that take qux<T>
as a parameter.
This makes polymorphism - a standard solution in such cases - not an obvious choice.
Sometimes though I need to create a qux<T>
while having only a variable holding a types
value, so it has to be mapped to the proper type somehow.
What I've been doing up until now is just switch
ing each time I have to do this but I hit the point where there's too many switch
es to maintain.
I don't see a better solution, so what I'm looking to do is create a single swich
or other mechanism in the code that will take types
value and return... something that will let me create a qux<T>
with related type.
Ultimately it'd work like this.
template<typename T>
void baz(qux<T> q) { /* ... */ }
// Somewhere else...
types t = get_type(); // Read type at runtime.
baz(create_object(t)); // Calls adequate baz specialization based on what value t contains.
I don't know how to implement the create_object
function though.
What I tried already:
std::variant
with careful use ofemplace
andindex
- quickly hit the problem of being unable to return different types from a single function;- clever use of conversion operators - doesn't allow me to call a proper templated function taking
qux<T>
as a parameter since it's not decided which specialization should be called; - external polymorphism - unable to return different types;
- modified template specialization loop proposed in this answer that looked for proper
types
value and returned mapped type - this failed due to being unable to return different types - or called a lambda withauto
parameter - which also failed as it tried to specialize the lambda multiple times.