views:

135

answers:

1

I am trying to write a generic allocator class that does not really release an object's memory when it is free()'d but holds it in a queue and returns a previously allocated object if a new one is requested. Now, what I can't wrap my head around is how to pass arguments to the object's constructor when using my allocator (at least without resorting to variadic templates, that is). The alloc() function i came up with looks like this:

template <typename... T>
inline T *alloc(const &T... args) {
    T *p;

    if (_free.empty()) {
        p = new T(args...);
    } else {
        p = _free.front();
        _free.pop();

        // to call the ctor of T, we need to first call its DTor
        p->~T();
        p = new( p ) T(args...);
    }
    return p;
}

Still, I need the code to be compatible with today's C++ (and older versions of GCC that do not support variadic templates). Is there any other way to go about passing an arbitrary amount of arguments to the objects constructor?

+4  A: 

When you need to target pre-C++0x compilers you need to provide pseudo-variadic templates, i.e. you need to provide a template function for every needed arity:

template<class T> 
T* alloc() { 
    /* ... */ 
}

template<class T, class A0> 
T* alloc(const A0& a0) { 
    /* ... */ 
}

/* ... */

You can use preprocessor metaprogramming though to handle the repititions, e.g. by using Boost.Preprocessor or by simply generating the functions using a simple script.

Following is a simple example using Boost.PP:

#include <boost/preprocessor/arithmetic/inc.hpp>
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>

template<class T>
T* alloc() {
    return new T;
}

#define FUNCTION_ALLOC(z, N, _) \
  template<class T, BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), class T)> \
  T* alloc(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_INC(N), const T, &p)) { \
     return new T( \
       BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_INC(N), p) \
     ); \
  }

BOOST_PP_REPEAT(10, FUNCTION_ALLOC, ~)

#undef FUNCTION_ALLOC

This generates you alloc() template functions for up to 10 arguments.

Georg Fritzsche
Can Boost help with that?
UncleBens
Yep, Boost.PP helps - i think @GMan had a nice example somewhere, will try to dig it up.
Georg Fritzsche
I do plenty of Boost Preprocessor stuff, but I don't think I've put much on the site. Matthieu did one recently, though: http://stackoverflow.com/questions/2597586/simplifying-templates/2598283#2598283
GMan
Didn't find what i had in mind, i probably confused it with something else. :)
Georg Fritzsche