Re: Generic factory method/abstract factory: Forwarding function signatures?
On 2011-06-17 01:04, Arne Mertz wrote:
Hello everybody,
in my current project I have a bunch of factories that do the creation
an destruction of their products in a more or less similar fashion and
have similar requirements. I'd like to stuff the "similar fashion"
part into a template and the "more or less" similar part into
policies. These are my requirements:
1) Some things might have to be done before and/or after the actual
creation/destruction of the product, e.g. storing a pointer to the
created object or checking that there are not more than N products
alive at a given time.
2) The Actual creation and destruction process can be changed at
runtime, as in the Abstract Factory Pattern
this is what i hav come up with so far:
template<class CreationSignature, class ManagementPolicy>
class GenericFactory : public ManagementPolicy
{
typedef typename boost::function<CreationSignature> Creator;
typedef typename boost::function_types::result_type< Signature
::type ResultType;
typedef boost::function<void(ResultType&)> Destructor;
Destructor destructor;
Creator creator;
public:
void exchangeDtor(Destructor const& d) {
destructor = d;
}
void exchangeCtor(Creator const& c) {
creator = c;
}
void destroy(ResultType& r) {
ManagementPolicy::preDestruction(r);
destructor(r);
ManagementPolicy::postDestruction();
}
ResultType create(THE_ARGS_THAT_ARE_NEEDED_FOR_CREATION)
{
ManagementPolicy::preCreation(THE_ARGS);
ResultType r = creator(THE_ARGS);
ManagementPolicy::postCreation(r);
return r;
}
};
*Question1*: is there any means to somehow deduce the "THE_ARGS_*"
from the CreationSignature template parameter?
No.
I know it would be
possible to reduce the arity of create and the Creator member to 1 by
stuffing any parameters into a boost::mpl container or tuple, but I
think it would be tedious for the factories' clients to build that
structure before actually calling the factory, and for the Creators to
take the parameters apart again.
If you are using a C++0x compatible compiler I would suggest to provide
a variadic function template of the following form:
template<class... Args>
ResultType create(Args... args);
In the C++03 world I suggest to use the approach from boost to generate
a set of overloads with standard machinery of macros. You may want to
look for BOOST_PP_ENUM_PARAMS, BOOST_PP_REPEAT_FROM_TO used within boost
for such purposes.
One step further, I'd like to provide additional template parameters
for default Creator and Destructor classes, in order to make the
factories usable right after their construction. One reason is that
I'd like to make those factories singletons. Yes, I know.
Singletons..... But I think that's not the point here. The constructor
would look like this:
template<class CreationSignature, class ManagementPolicy, class
DefaultCreator, class DefaultDestructor>
GenericFactory<CreatoinSignature, ManagementPolicy, DefaultCreator,
DefaultDestructor>::GenericFactory()
: creator(DefaultCreator())
, destructor(DefaultDestructor())
{}
*Question2*: Is there a possibility to deduce the CreationSignature
from the DefaultCreator template parameter? (and would you think it is
worth the effort?)
A constructor is too late for this, because the constructor already
belongs to a specific specialization, therefore no further deduction is
possible. I would suggest to use a traits_class for this purpose. This
allows to customize the defaults on an independent design axes.
HTH & Greetings from Bremen,
- Daniel Kr?gler
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]