你可以尝试做和 Boost 一样的事情,例如在Boost.Function(链接到模板头)。他们使用Boost.Preprocessor 在给定数量的参数上枚举各种事物。例如,假设您想为 0-2 个参数重载一个函数。常规方式如下:
void foo(){...}
template<class T0>
void foo(T0 a0){...}
template<class T0, class T1>
void foo(T0 a0, T1 a1){...}
现在 Boost 所做的就是将这些模板参数(class T0 等)放入预处理器宏中,在函数内部使用它,然后针对不同数量的参数包含 3 次标头。示例:
// template header, no include guard
#define FOO_TEMPLATE_PARAMS BOOST_PP_ENUM_PARAMS(FOO_NUM_ARGS,class T)
#define FOO_PARAM(J,I,D) BOOST_PP_CAT(T,I) BOOST_PP_CAT(a,I)
#define FOO_PARAMS BOOST_PP_ENUM(FOO_NUM_ARGS,FOO_PARAM,BOOST_PP_EMTPY)
#if FOO_NUM_ARGS > 0
#define FOO_TEMPLATE template< FOO_TEMPLATE_PARAMS >
#else
#define FOO_TEMPLATE
#endif
FOO_TEMPLATE
void foo(FOO_PARAMS){...}
// cleanup what we've done
#undef FOO_TEMPLATE_PARAM
#undef FOO_TEMPLATE_PARAMS
#undef FOO_PARAM
#undef FOO_PARAMS
#undef FOO_TEMPLATE
上面是模板头,我们称之为Foo_Template.h。现在我们只需将它包含在我们想要的参数数量中:
// Foo.h
#include <boost/preprocessor.hpp>
#define FOO_NUM_ARGS 0
#include "Foo_Template.h"
#define FOO_NUM_ARGS 1
#include "Foo_Template.h"
#define FOO_NUM_ARGS 2
#include "Foo_Template.h"
#define FOO_NUM_ARGS 3
#include "Foo_Template.h"
#define FOO_NUM_ARGS 4
#include "Foo_Template.h"
#undef FOO_NUM_ARGS
完美!通过更多的预处理器工作和样板“代码”,我们现在可以为任意数量的参数重载 foo!预处理器宏将扩展为如下内容:
// with FOO_NUM_ARGS == 0
#define FOO_TEMPLATE_PARAMS /*empty, because we enumerate from [0,FOO_NUM_ARGS)*/
#define FOO_PARAMS /*empty again*/
#define FOO_TEMPLATE /*empty, we got the 0 args version*/
void foo(){...}
// with FOO_NUM_ARGS == 1
#define FOO_TEMPLAtE_PARAMS class T0 /* BOOST_PP_ENUM is like a little for loop */
#define FOO_PARAMS T0 a0
#define FOO_TEMPLATE template< class T0 >
template< class T0 >
void foo( T0 a0 ){...}
// with FOO_NUM_ARGS == 3
#define FOO_TEMPLAtE_PARAMS class T0, class T1, class T2
#define FOO_PARAMS T0 a0, T1 a1, T2 a2
#define FOO_TEMPLATE template< class T0, class T1, class T2 >
template< class T0, class T1, class T2 >
void foo( T0 a0, T1 a1, T2 a2 ){...}
幸好有了可变参数模板,我们在 C++0x 中不再需要它了。我爱他们。