任何元编程方式生成重载的各种数量的模板参数? [英] Any metaprogramming way to generate overloads for various numbers of template parameters?

查看:89
本文介绍了任何元编程方式生成重载的各种数量的模板参数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一组函数模板,可以采用不同类型和数量的参数,如下所示:

I'm trying to create a set of function templates that can take different types and numbers of parameters, like this:

template <T0>
void call(T0 arg0);

template <T0, T1>
void call(T0 arg0, T1 arg1);

template <T0, T1, T2>
void call(T0 arg0, T1 arg1, T2 arg2);

template <T0, T1, T2, T3>
void call(T0 arg0, T1 arg1, T2 arg2, T3 arg3);

template <T0, T1, T2, T3, T4>
void call(T0 arg0, T1 arg1, T2 arg2, T3 arg3, T4 arg4);

[...]

函数(作为单参数模板函数的参数)。这是一个图书馆,所以额外的努力,我的一部分是可以接受的,如果它意味着更少的努力或更好的图书馆用户的界面。

The parameters are all treated the same within the functions (as arguments to a single-parameter template function). This is for a library, so extra effort on my part is acceptable, if it means less effort or a more pleasing interface for the library user.

为不同的项目做这个好几次,我真的很累,不得不手动编写所有的。当我事先不知道项目使用库需要的参数的最大数量时会变得更糟。

I've had to do this several times for different projects, and I'm heartily tired of having to manually write all of them by hand. It gets worse when I don't know beforehand the maximum number of parameters the project using the library will need.

在我开始编写一个Python脚本生成所有的重载,是否有一些元编程方式让编译器为我做它?

Before I start writing a Python script to generate all of the overloads, is there some metaprogramming way to have the compiler do it for me instead?

推荐答案

你可以尝试做同样的事情如Boost所做,例如在 Boost.Function (链接到模板标题)。他们使用 Boost.Preprocessor 枚举给定的各种内容参数个数。例如,考虑你想重载一个0-2参数的函数。常规方式如下:

You can try and do the same thing as Boost does, for example in Boost.Function (link to the template header). They use Boost.Preprocessor to enumerate various things on the given number of arguments. For example consider you want to overload a function for 0-2 arguments. The conventional way would be the following:

void foo(){...}
template<class T0>
void foo(T0 a0){...}
template<class T0, class T1>
void foo(T0 a0, T1 a1){...}



do,只是把那些模板参数(类T0 等)放入一个预处理器宏,使用函数内部,然后包含头3次不同数量的参数。示例:

Now what Boost does, is to just put those template parameters (class T0 etc) into a preprocessor macro, use that inside the function, and then include the header 3 times for different number of arguments. Example:

// 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 。现在我们只需要包含它的参数数量:

The above is the template header, lets call it Foo_Template.h. Now we just include it for the number of arguments we want:

// 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!预处理器宏将扩展为这样:

Perfect! With a little more preprocessor effort and boilerplate "code", we can now overload foo for any number of arguments! The preprocessor macros will expand to something like this:

// 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感谢可变模板。我爱他。

But it's a bliss we won't need this anymore with C++0x thanks to variadic templates. I love 'em.

这篇关于任何元编程方式生成重载的各种数量的模板参数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆