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?
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With