Re: type-safe varargs
On Dec 19, 10:38 pm, Tim H <thoc...@gmail.com> wrote:
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?
void func(const std::vector<boost::any> &);
or if you want to change the arguments:
void func(std::vector<boost::any> &);
upside is that boost::any can encapsulate anything with a copy
constructor including POD types.
You could write simple functions for any possible argument combination
which return a vector, e.g.
std::vector<boost::any> createVectorByStringAndInt(const std::string
&_r0, const int _i1)
{ std::vector<boost::any> s;
s.push_back(_r0);
s.push_back(_i1);
return s;
}
then you could do
std::string s0;
int i1;
func(createVectorByStringAndInt(s0, i1));
Be aware that using boost::any is not free.
When creating a boost::any an object is allocated on the heap and the
passed object is copy-constructed.
Same for copying boost::any.