Variable number of arguments possible?


#1

Is there a way to define a C++ function to be injected into a chaiscript script such that in the script the function would allow a variable number of arguments? In other words, in the script world, I’d like to be able to write

foo(“a”, “b”);

for(“a”, “b”, “c”, “d”)

and so forth ---- obviously if one was limited to just a few args one could use overloading but I would like to allow an arbitrary number of args to be supplied without having to push them on to an array (for example)

Thanks,
D


#2

Sorry for the slow response…

It is theoretically possible for it to be added, but the feature doesn’t exist yet.

What you can do, today, is an array of arguments:


def foo(Vector v)
{
  // do something with each element of v...
}

foo(["a", "b", "c"])

Would that do what you want?


#3

Am I correct in assuming that variadic template doesn’t supports now?
So, I cannot use variadic functions as a callback.


 template
 T funcSum( Args... args) {
	 ...;
 }
chai.add(fun([](auto...args) {return funcSum(args...); }), "funcSum");

#4

No, that’s impossible with C++. You need a concrete function type which a template or variadic function / lambda does not give you.


#5

One problem is that you can’t declare a vector using the array initialization syntax and have its members be references. (They’re always copies, as I understand it.) So you can’t do:

auto x = 5;
auto y = 10.3;
[x, y].for_each(fun(o) { o += 100 });
for (o : [x, y]) { print(o) }; // Hmm...still have original values; worked on a copy

As I understand it, the only way to do this now would be:

auto objs = [];
objs.push_back_ref(x);
objs.push_back_ref(y);
objs.for_each(fun(o) { o += 100 });
for (o : objs) { print(o) }; // good: we modified the values

So what? (-; Well, the reason this relates to this discussion thread is that I thought of creating a helper function that would take a variable number of arguments and return a vector, with the arguments added to the vector as refs (using push_back_ref()). However, if we can’t do variable numbers of function arguments, this isn’t really a solution.

Thanks – any suggestions of other (shorter, more elegant) ways to do this? Any chance ChaiScript could expose a ref() function, as in C++ std::ref()? Then you could make your intentions explicit, and write:

for (o : [ref(x), ref(y)]) { o.modifySomehow() }
// or
[ref(x), ref(y)].for_each(fun(o) { o.modifySomehow() })

Thanks!


#6

Strangely, I’ve discovered that Pair() seems to add its members as references by default. So the following actually works, as a kind of “heavyweight” version of a ref() function:

// Try with Pairs; it seems they hold refs by default:
auto x = 5;
auto y = 10.3;
for (o : [Pair(x, 0), Pair(y, 0)]) { o.first -= 37 };
for (o : [x, y]) { print(o) }; // good: we modified the original values

Is this the expected behaviour?


#7

By default everything is a reference, it’s actually a special case that makes copies for the inline array/map syntax, so I’d say that yes, it’s working as expected.


#8

It is possible to add function overloads to emulate optional arguments: