I need to call a function passed as argument to another function and it must be passed its needed arguments firstly. In c++, this problem is solved with a macro:
#include <iostream>
#define CALL(x) x; \
std::cout << "Called!" << std::endl;
void foo(int a, int b)
{
std::cout << a * b << std::endl;
}
int main()
{
CALL(foo(9, 8)); // I want to pass 2 int parameters inside 'foo' function call
system("PAUSE");
}
It sould output:
> 72
> Called!
That is exactly how I need to call the function in D. Any ideas?
Edit: I need this to be done in D. I want to call "foo" inside CALL like:
CALL(foo(9, 8)) // and not like: CALL(foo, 9, 8)
But I don't know how this is achieved in D. Perhaps with a mixin?
The call by reference method of passing arguments to a function copies the address of an argument into the formal parameter. Inside the function, the address is used to access the actual argument used in the call. It means the changes made to the parameter affect the passed argument.
We cannot pass the function as an argument to another function. But we can pass the reference of a function as a parameter by using a function pointer. This process is known as call by reference as the function parameter is passed as a pointer that holds the address of arguments.
Arguments are passed by value; that is, when a function is called, the parameter receives a copy of the argument's value, not its address. This rule applies to all scalar values, structures, and unions passed as arguments. Modifying a parameter does not modify the corresponding argument passed by the function call.
In D, you can use a lazy
function parameter for this.
import std.stdio;
void CALL(lazy void x) {
writeln("before called");
x;
writeln("after called");
}
void foo(int x, int y) {
writeln(x, " ", y);
}
void main() {
CALL(foo(3, 5));
}
D's lazy
parameter storage class causes the compiler to wrap whatever you give it in a little anonymous function. The above is as if you wrote:
import std.stdio;
void CALL(void delegate() x) { // note delegate here in long-form syntax
writeln("before called");
x();
writeln("after called");
}
void foo(int x, int y) {
writeln(x, " ", y);
}
void main() {
// and this delegate too
CALL( delegate() { return foo(3, 5); } );
}
But the compiler rewrites it for you. This is why I said lazy void
- the void
there is the return type of the hidden function you pass. If it returned int
, you could use lazy int
instead.
Note that since x
inside the CALL
function is rewritten to be a hidden function, calling it twice will actually evaluate the arguments twice:
void CALL(lazy void x) {
writeln("before called");
x;
writeln("after called");
x;
writeln("after called again");
}
would do:
before called
3 5
after called
3 5
after called again
Notice how it printed out the arguments twice. Just like the C macro, actually. But if that's not what you want, simply assign it to a temporary yourself:
void CALL(lazy int x) {
auto tmp = x;
// you can now use tmp as a plain int
}
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