From: Tobias Schwinger (tschwinger_at_[hidden])
Date: 2007-06-17 17:53:23


Dear Boost community,

do we have a function object template to wrap arbitrary constructor
calls / operator new expressions somewhere in Boost, already?

If not, is there any interest in such a thing?

Interface draft:
================

     factory<T> // constructs X and returns it by value
     factory<T*> // uses operator new, returns a pointer

Where operator() takes a variable number of arguments, forwarded to the
constructor.

Should there be an optional 'Allocator' template parameter?

Some use cases:
===============

o Transform through an explicit constructor, e.g:

     std::transform(from,to,out,factory<X>());

or a constructor that takes more than one argument, e.g:

     std::transform(from,to,out,
         boost::bind(factory<Y>(),12,_1));

o Generate data, e.g:

     std::generate_n(out,12,boost::bind(factory<Y>(),123,12));

o Creating homogeneous, polymorphic factories from heterogeneous
constructors, e.g:

     void register_factory( std::type_info const &,
         boost::function<void*()> const &);

     // ... at function scope:

     register_factory( typeid(X), factory<X>() );
     register_factory( typeid(Y), boost::bind(factory<Y>(),12,1) );

Implementation notes regarding the Forwarding Problem:
======================================================

For now (C++89) it might be good enough to just have operator() take its
arguments by non-const reference. As usually the call will be deferred
and as long as the arguments are L-Values they will be deduced even if
const qualified (this might break the code of the first use case above -
wrapping the factory specialization into a Boost.Bind function object
without actually binding anything will work around the problem, though).

Alternatively we could solve the forwarding problem (within the function
object itself) using a "hammer and crowbar utility" in Fusion
(overloading operator() with all combinations of templatized
const/non-const reference parameters) until we have better means to do
so. I personally prefer the former because it's more lightweight and
might allow us to be more portable than Fusion is, however.

Curiously awaiting your feedback,
Tobias