类型安全的varargs [英] type-safe varargs

查看:52
本文介绍了类型安全的varargs的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标:提供最简单的呼叫站点,费用为
前期hackery。


我有一个功能基本上需要一个变量列表参数:


func(const string& k0,unsigned long long v0,const string& k1,

unsigned long long v1等)


这将从手写的代码中被称为很多,所以我ñ
真的很简单,以简化调用此函数的工作。 />

我找到的选项:


使用varargs。

func(...)

这有简单和无限的优点。它的缺点是限制内置类型 - char *而不是字符串。它b / b
也有迫使调用者确保文字整数的缺点

是ULL,以免我们使堆栈失衡。

使用C pre -processor hackery获取__VA_ARGS__来初始化数组

arg。

#define FUNC(...)FUNC _((kvpair []){__ VA_ARGS__,{NULL}} )

只要你在

电话中使用任何文字,这就会失败。并且语法混淆了我有的每个语法着色应用程序

见过:

使用默认args。

func(const string& k0,unsigned long long v0,

const string& k1 ="" ;, unsigned long long v1 = 0,

const string& k2 ="",unsigned long long v2 = 0,

const string& k3 ="",unsigned long long v3 = 0,

const string& k4 ="" ,unsigned long long v4 = 0)

这具有类型安全且易于调用的优点。它有一个缺点,我需要扩展args列表以覆盖最差的

案例来电,并在每次通话时支付这笔费用。

任何人都可以提出更好的设计吗?

Goal: to provide the simplest call-site possible at the cost of
upfront hackery.

I have a function that essentially takes a variable list of arguments:

func(const string &k0, unsigned long long v0, const string &k1,
unsigned long long v1, etc)

This is going to be called a LOT from code that is hand-written, so I
really ant to simplify the job of calling this function.

Options I have found:

Use varargs.
func(...)
This has the plus of being simple and unlimited. It has the downside
of being limited to built-in types - char * rather than string. It
also has the downside of forcing the caller to make sure literal ints
are ULL, lest we unbalance the stack.
Use C pre-processor hackery to get __VA_ARGS__ to initialize an array
arg.
#define FUNC(...) FUNC_((kvpair[]){__VA_ARGS__, {NULL}})
This falls down as soon as you use anything but a literal in the
call. And the syntax confuses every syntax coloring app I have
seen :)
Use default args.
func(const string &k0, unsigned long long v0,
const string &k1="", unsigned long long v1=0,
const string &k2="", unsigned long long v2=0,
const string &k3="", unsigned long long v3=0,
const string &k4="", unsigned long long v4=0)
This has the upside that it is type-safe and simple to call. It has
the downside that I need to extend the args list to cover the worst
case caller, and pay that cost at every call.
Can anyone suggest a better design?

推荐答案

12月20日上午6:38,Tim H< thoc ... @ gmail.comwrote :
On Dec 20, 6:38 am, Tim H <thoc...@gmail.comwrote:

目标:提供最简单的呼叫站点,费用为
前期hackery。


我有一个函数,它基本上采用变量参数列表:


func(const string& k0,unsigned long long v0,const string& k1,

unsigned long long v1等)


这将从手写的代码中调用很多,所以我

非常简化调用此功能的工作。


我找到的选项:


使用varargs。

func(...)

这有简单和无限的优点。它的缺点是限制内置类型 - char *而不是字符串。它还有一个不利因素,即迫使调用者确保文字整数

是ULL,以免我们使堆栈失衡。


使用C预处理器hackery获取__VA_ARGS__来初始化数组

arg。

#define FUNC(...)FUNC _((kvpair []){__ VA_ARGS__, {NULL}})

只要在

调用中使用除文字之外的任何内容,这种情况就会失效。并且语法混淆了我所有的语法着色应用程序

见过:


使用默认args。

func(const string& ; k0,unsigned long long v0,

const string& k1 ="",unsigned long long v1 = 0,

const string& k2 =" ",unsigned long long v2 = 0,

const string& k3 ="",unsigned long long v3 = 0,

const string& k4 = "",unsigned long long v4 = 0)

这样做的好处是类型安全且易于调用。它有一个缺点,我需要扩展args列表以覆盖最差的

案例来电,并在每次通话时支付这笔费用。

有谁能建议更好的设计?
Goal: to provide the simplest call-site possible at the cost of
upfront hackery.

I have a function that essentially takes a variable list of arguments:

func(const string &k0, unsigned long long v0, const string &k1,
unsigned long long v1, etc)

This is going to be called a LOT from code that is hand-written, so I
really ant to simplify the job of calling this function.

Options I have found:

Use varargs.
func(...)
This has the plus of being simple and unlimited. It has the downside
of being limited to built-in types - char * rather than string. It
also has the downside of forcing the caller to make sure literal ints
are ULL, lest we unbalance the stack.

Use C pre-processor hackery to get __VA_ARGS__ to initialize an array
arg.
#define FUNC(...) FUNC_((kvpair[]){__VA_ARGS__, {NULL}})
This falls down as soon as you use anything but a literal in the
call. And the syntax confuses every syntax coloring app I have
seen :)

Use default args.
func(const string &k0, unsigned long long v0,
const string &k1="", unsigned long long v1=0,
const string &k2="", unsigned long long v2=0,
const string &k3="", unsigned long long v3=0,
const string &k4="", unsigned long long v4=0)
This has the upside that it is type-safe and simple to call. It has
the downside that I need to extend the args list to cover the worst
case caller, and pay that cost at every call.

Can anyone suggest a better design?



如何封装所有参数的对象。


类似(缩短示例):

struct Params {

string& k1;

string& k2;

ull v1;

ull v2;

Params(const string& k1,const string& k2):k1(k1), k2(k2),v1(0),

v2(0){}

参数(const string& k1,ull v1):k1(k1),v1( v1),v2(0){}

参数(const string& k1,ull v1,ull v2):k1(k1),v1(v1),v2(v2){}

//等 - 只需要覆盖你使用的排列

};


然后。


extern void func(const Params&);



func(Params(" foo"," bar"));

func(Params(" baz",123345ULL));

func(Params(" yadda",123344ULL,789010ULL));




How about an object to encapsulate all the parameters.

Something like (foreshortened example):
struct Params {
string& k1;
string& k2;
ull v1;
ull v2;
Params(const string& k1, const string&k2) : k1(k1), k2(k2), v1(0),
v2(0) {}
Params(const string& k1, ull v1) : k1(k1), v1(v1), v2(0) {}
Params(const string& k1, ull v1, ull v2) : k1(k1), v1(v1), v2(v2) {}
// etc - only need to cover the permutations you use
};

then.

extern void func(const Params&);
:
func(Params("foo", "bar"));
func(Params("baz", 123345ULL));
func(Params("yadda", 123344ULL, 789010ULL));

etc.


12月20日上午11:19,tragomaskhalos< dave.du.verg ... @ logicacmg.com>

写道:
On Dec 20, 11:19 am, tragomaskhalos <dave.du.verg...@logicacmg.com>
wrote:

>

类似(缩短示例):

struct Params {

string& k1;

string& K2;
>
Something like (foreshortened example):
struct Params {
string& k1;
string& k2;



哎呀。应该是

const string& k1;

const string& k2;

我认为这可以解决临时终身问题,

希望有人会拍我但如果没有。

Oops. Should be
const string& k1;
const string& k2;
I think this is OK wrt binding-to-temporary lifetime issues,
hopefully someone will shoot me down if not.


12月20日凌晨3:41,tragomaskhalos< dave.du.verg ... @ logicacmg.com>

写道:
On Dec 20, 3:41 am, tragomaskhalos <dave.du.verg...@logicacmg.com>
wrote:

12月20日上午11点19分,tragomaskhalos< dave.du.verg ... @ logicacmg.com>

写道:
On Dec 20, 11:19 am, tragomaskhalos <dave.du.verg...@logicacmg.com>
wrote:

类似(缩短示例):

struct Params {

string& k1;

string& K2;
Something like (foreshortened example):
struct Params {
string& k1;
string& k2;



哎呀。应该是

const string& k1;

const string& k2;

我认为这可以解决临时终身问题,

希望如果不是,有人会把我击倒。


Oops. Should be
const string& k1;
const string& k2;
I think this is OK wrt binding-to-temporary lifetime issues,
hopefully someone will shoot me down if not.



我仍​​然需要提供一个具有32对(kn,vn)或

32个不同构造函数的构造函数。至少有32个不同的ctors,我不会支付b
。它仍然很可怕:)

I still need to provide a constructor that has 32 pairs of (kn, vn) or
32 different constructors. At least with 32 different ctors, I don''t
pay the perf cost. It''s still hideous :)


这篇关于类型安全的varargs的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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