
Hi Marco, Marco Costalba wrote:
I have found a solution this way (and it works):
These are the overloads according to the number of arguments (I just show 2 of them)
template<typename T1> static Base* object(detail::KeyRef nm, T1 a1)
This one will fail to compile with a non-copyable argument for 'a1' (unless 'T1' is specified explicitly to be a reference).
BTW I studied your factory and also your suggestion to use a map as a dispatcher to create a complete object factory from your one.
OK, so we're basically talking about this one (from boost.user, some time ago - cited from memory and possibly full of errors) // assuming 'an_abstract' base and 'a_concrete', default // constructible sub class std::map< std::string, boost::function< an_abstract*() > > map_factories; map_factories["a_concrete"] = boost::factory<a_concrete>(); , arent't we?
The problem is that the classes must be registered at instantation time.
The code above does not create objects of the classes - it just generates (or references already-generated) code to do so.
IOW your factory (+ a map framework to act as dispatcher) does not seem to support the concept of adding new classes at runtime, everything must be already known at instantation/definition time.
Well, C++ never ever generates code at runtime... However, you sure can add another element to that map: // assuming 'another_concrete', default constructible // sub class map_factories["another_concrete"] = boost::factory<another_concrete>(); Maybe you mean that 'boost::factory<a_concrete>' and 'boost::factory< another_concrete>'are distinct (even incompatible) types? The clue is that both can be turned into objects of type 'boost::function<an_abstract*() >' to become polymorphic runtime entities. Marco Costalba wrote (in the other post):
All this dynamic plomorphism stuff is, again, necessary (at least I haven't found nothing better) _only_ because supported classes are not known at factory instantation time. If it was known I could use a fusion map to store everything and the trick is done.
Boost.Function is basically a factorization of a virtual operator(). See its documentation for details: http://www.boost.org/libs/function
But a fusion map cannot be changed at runtime! If you add new classes to your map you have a _new_ map type. So you cannot foreseen a map variable as a member data.
I know :-). Use an STL map like I did in the example (guessing you might have misread a sidenote of mine about using a fusion::map in addition to a std::map to support several signatures). Regards, Tobias