Re: How to simulate variadic templates?
On 8 Jun, 06:07, Peter Holtwick <peterholtw...@gmail.com> wrote:
Sorry I'm not sure I understand, do you mean something like:
template<class T, class A1, class A2, class A3, class A4>
Ptr<T> New( A1 a1, A2 a2, A3 a3, A4 a4) {/* factory */ }
and then specializations i.e.
template<class T, class A1, void, void, void>
Ptr<T> New( A1 a1) {/* factory */ }
I would suggest starting with a simple solution and making it
more robust and more complicated if you feel a need for that.
First, create overloads for 0-N arguments manually. Here is
the solution for N == 2.
template <class T>
Ptr<T> New() { return Ptr<T>(new T()); }
template <class T, class A0>
Ptr<T> New(A0 a0) { return Ptr<T>(new T(a0)); }
template <class T, class A0, class A1>
Ptr<T> New(A0 a0, A1 a1) { return Ptr<T>(new T(a0, a1)); }
With this simple solution you already can use your shiny
'New' function with convenient syntax.
Ptr<int> i = New(42);
Ptr<complex<double> > = New<complex<double> >(2.5, 3.6);
If you want to use it with objects that have constructors
with more than 2 arguments then just add more overloads
for New.
Now, if you have enough courage, you can rewrite it using
boost preprocessor.
#include <boost/preprocessor.hpp>
#ifndef NEW_MAX_ARGUMENTS_NUMBER
# define NEW_MAX_ARGUMENTS_NUMBER 10
#endif
#define BOOST_PP_LOCAL_MACRO(N) \
template <class T \
BOOST_PP_COMMA_IF(N) \
BOOST_PP_ENUM_PARAMS(N, class A)> \
Ptr<T> New(BOOST_PP_ENUM_BINARY_PARAMS(N, A, a)) { \
return Ptr<T>(new T(BOOST_PP_ENUM_PARAMS(N, a))); \
}
#define BOOST_PP_LOCAL_LIMITS (0, NEW_MAX_ARGUMENTS_NUMBER)
#include BOOST_PP_LOCAL_ITERATE()
It generates the same overloads for 0-9 arguments. Upper limit
can be configured in compile time (just define
NEW_MAX_ARGUMENTS_NUMBER macro).
Now you can notice that your 'New' function does not work
with types that don't have copy constructors, and you can't
pass a reference as an argument. It's called 'perfect
forwarding problem' and it's not that easy to solve
(see http://std.dkuug.dk/JTC1/SC22/WG21/docs/papers/2002/n1385.htm).
In C++0x it has elegant solution, but for now I'd recommend using
boost::forward library (it was accepted but not released yet) or
'perfect' from egg library
(http://p-stade.sourceforge.net/egg/doc/html/egg/
function_adaptors.html#egg.function_adaptors.perfect).
Roman Perepelitsa.
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]