6

Same question as here except using C++98:

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

My typedef is of the form: typedef Type1 (*pf)(Type2, Type3, ...)

How do I template this typedef?

Only Type1 is required.

I manually write:

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

I'm looking for something like:

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

Is that correct?

Community
  • 1
  • 1
Bob
  • 4,576
  • 7
  • 39
  • 107

1 Answers1

4

You can use Boost.Preprocessor to simulate variadic templates in C++98. What is actually done behind the scenes is that the preprocessor writes all the specializations of the template for different numbers of parameters for you. You can now use the typedef in varadic<...>::type with up to 256 template arguments.

With templates it is not such a problem because only instantiated templates go into the binary but for non-template entities this can result in 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 standard was ratified, there is no reason not to switch to C++11. Still using C++98 is kind of like still 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

Henri Menke
  • 10,705
  • 1
  • 24
  • 42
  • True enough; but some people still may have "retro - pc's" from back in the day that they are "tinkering" with as a hobby or for some other reason and may be limited to which versions of an OS - Applications\Programs they can use. It is rare to see a `C++98` question pop up, but I still think it is good for `Legacy` or `Historical` reasons. I can remember being in my H.S. computer science class working with both Visual Basic and C++ and they were on Windows 95/98 machines because Windows XP wasn't even out yet. I was still fluent in DOS back then and Q-Basic! I did give you a thumbs :) – Francis Cugler May 19 '17 at 05:59
  • 2
    @FrancisCugler: There's a RetroComputing SE site. And as C++98 is from another century, I'd agree it qualifies as retro. – MSalters May 19 '17 at 08:36
  • Also think about the embedded developers which are stuck on an old system which isn't upgradable and are forced to use an old c 98 compiler... – BenHero Oct 06 '21 at 08:34