Variadic template for defining a typedef (using C ++ 98)

Same question as here , except using C ++ 98:

I've just defined 4 different typedefs with minimal differences, and I'm wondering if there is a way to use templates to do this more efficiently.

My typedef looks like: typedef Type1 (*pf)(Type2, Type3, ...)

How do I customize this typedef?

Only required Type1

.

I manually write:

typedef int (*pf)(int)
typedef bool (*pf)()
typedef char (*pf)(bool, int)

      

I am looking for something like:

template <Type T1,Type...Rest>
typedef T1 (*pf)(Type...Rest)

      

Is it correct?

+3


source to share


1 answer


You can use Boost.Preprocessor to model variadic templates in C ++ 98. What is actually done behind the scenes is that the preprocessor writes all template specializations for different parameter numbers for you. You can now use typedefs varadic<...>::type

with up to 256 template arguments.

With templates this is not such a problem because only instantiated templates end up in binaries, but for non-templated objects this can lead to massive code bloat.

#include <iostream>
#include <boost/preprocessor/config/limits.hpp>
#include <boost/preprocessor/repeat.hpp>
#include <boost/preprocessor/facilities/intercept.hpp>
#include <boost/preprocessor/repetition/enum_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_params.hpp>
#include <boost/preprocessor/repetition/enum_trailing_binary_params.hpp>

// Macro to generate specializations
#define MAKE_VARIADIC(Z, N, _)                                          \
  template <                                                            \
    typename R                                                          \
    BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, typename T)                   \
      >                                                                 \
  struct variadic < R BOOST_PP_ENUM_TRAILING_PARAMS_Z(Z, N, T) >        \
  {                                                                     \
    typedef R (*type)(BOOST_PP_ENUM_PARAMS_Z(Z, N, T));                 \
  };

// Declare variadic struct with maximum number of parameters
template <
  typename R
  BOOST_PP_ENUM_TRAILING_BINARY_PARAMS(BOOST_PP_LIMIT_ITERATION, typename T, = void BOOST_PP_INTERCEPT)
    >
struct variadic;

// Repeat macro to create all specializations
BOOST_PP_REPEAT(BOOST_PP_LIMIT_ITERATION, MAKE_VARIADIC, nil)


// Function to print what was derived
template < typename T >
void print_T()
{
  std::cout << __PRETTY_FUNCTION__ << '\n';
}

// Test
int main ()
{
  print_T< variadic<int, double, float>::type > ();
}

      

Demo on Wandbox




However, it is much more convenient to use C ++ 11 alias templates for this kind of thing, and today in 2017, 6 years after the ratification of the standard, there is no reason not to switch to C ++ 11. Still using C ++ 98 is like using Windows XP.

#include <iostream>

template <typename R, typename ... Args>
using pf = R(*)(Args...);

// Function to print what was derived
template < typename T >
void print_T()
{
  std::cout << __PRETTY_FUNCTION__ << '\n';
}

// Test
int main ()
{
  print_T< pf<int, double, float> > ();
}

      

Demo on Wandbox

+2


source







All Articles