How to choose a function at run time using overloaded resolution in #Cpp?
I feel it's an old known issue without (obvious) answer, but many things changed since c++98
https://stackoverflow.com/questions/64031769/choose-a-function-at-run-time-using-overloaded-resolution-in-c
I add the new following constrain to my original question, it can be up to C++14, no more (although if a solution in c++17 or C++20 exist, I'm interested) because of compiler limitation (appears to be based on gcc 5.14 from what I understood).
But I allow complete refactoring code, even the b and d1 & d2. Templates, new classes and sub classes and even #define are fine (I already put 100-lines define to add iterator to enum and another one to allow enum inheritance, and my coworkers begin to hate me ^^)
For example, method "create" can become a class, or class b can be construct using a macro to make somehow the base class aware of derived ones
#define BASE(b, ...) std::tuple< __VA_ARGS__ > g_ ## b; class b
The only thing that really matter is, at the end of the day, to choose the correct method automatically without conditional statement at runtime. I really wonder is a workaround is possible.
I already tried to add "std::tuple< d1*, d2 > b_tuple" to class b, using some forward declaration, but, of course, std::get< i >(b_tuple) cannot compile since it will be known at runtime only.
@clement your question does not seem to match your example code very well. Overload resolution at runtime implies a lot of things, and yet the example seems like a simple case of runtime polymorphism, in which case you could just use virtual functions.
A newer alternative for runtime polymorphism is std::variant or boost::variant, which in a way is closer to runtime overload resolution. You can use a variant with all possible types and a function object that can accept all the types in question(this is called a visitor). With later standards you can use a generic lambda as a visitor. Something like this:
variant<d1,d2> var = d1();
cout << visit( [](auto& x) { return create(x); }, var );
In your example the app class itself can be the function object if you use operator() instead of create:
cout << visit(*this, var);
You can think of it as a switch statement on the type of the variant. If you also need to distinguish between different number of arguments (which overload resolution does), you can use a variant of tuples and something like std::apply in the visitor, to pass the tuple as parameters.