I was wondering if in C/C++ language it is possible to pass arguments to function in key-value form. For example in python you can do:
def some_function(arg0 = "default_value", arg1):
# (...)
value1 = "passed_value"
some_function(arg1 = value1)
So the alternative code in C could look like this:
void some_function(char *arg0 = "default_value", char *arg1)
{
;
}
int main()
{
char *value1 = "passed_value";
some_function(arg1 = value1);
return(0);
}
So the arguments to use in some_function would be:
arg0 = "default_value"
arg1 = "passed_value"
Any ideas?
Here's a C99 solution using compound literals and variadic macros:
#include <stdio.h>
#define some_func(...) some_func_((struct some_func_args_){ __VA_ARGS__ })
struct some_func_args_
{
const char *arg1;
const char *arg2;
};
static void some_func_(struct some_func_args_ args)
{
if(!args.arg1) args.arg1 = "default";
printf("---\narg1 = %s\narg2 = %s\n", args.arg1, args.arg2);
}
int main(void)
{
some_func("foo", "bar");
some_func(.arg1 = "spam");
some_func(.arg2 = "eggs");
return 0;
}
You can emulate this in C++ with this:
struct params {
string foo_;
double bar_;
short xxx_;
params() : foo_("123"), bar_(3.1415), xxx_(42) {} // default parameters
params& foo(string s) {foo_=s;return *this;}
params& bar(double x) {bar_=x;return *this;}
params& xxx(short x) {xxx_=x;return *this;}
};
void some_function(params const & p);
int main() {
some_function(params().bar(99.9).xxx(23));
}
But IMHO it's not worth the effort. Too much boiler plate.
If I remember correctly Stroustrup's book "Design and Evolution of C++" contains a section that discusses this feature request of "named arguments". The conclusion was something along the lines of: not a good idea. Check it out if you want details.
Named arguments are not supported in C, but you could emulate named parameters it using variadic function (though you loose type safety):
#include <stdarg.h>
void do_sth (int foo, ...)
{
int baz = 7; /* "baz" argument */
const char *xyz = "xyz"; /* "xyz" argument */
/* Parse named parameters */
va_list ap;
va_start (ap, foo);
for (;;) {
const char *key = va_arg (ap, char *);
if (key == NULL) {
/* Terminator */
break;
} else if (strcmp (key, "baz") == 0) {
baz = va_arg (ap, int);
} else if (strcmp (key, "xyz") == 0) {
xyz = va_arg (ap, char *);
} else {
/* Handle error */
}
}
va_end (ap);
/* do something useful */
}
do_sth (1, NULL); // no named parameters
do_sth (2, "baz", 12, NULL); // baz = 12
do_sth (3, "xyz", "foobaz", NULL); // xyz = "foobaz"
do_sth (4, "baz", 12, "xyz", "foobaz", NULL); // baz = 12, xyz = "foobaz"
Just remember to end optional arguments list with NULL. You could also use some ENUM as keys instead of character strings.
This technique is used, for exapmle, in GTK+:
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