Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to call a function passed as argument with its parameters already given in D?

Tags:

d

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?

like image 348
David Bermejo Avatar asked Nov 22 '17 15:11

David Bermejo


People also ask

How do you call a function with a parameter?

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.

How do you pass a function as an 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.

What is it called when you pass a function as an argument?

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.


1 Answers

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
}
like image 128
Adam D. Ruppe Avatar answered Oct 11 '22 00:10

Adam D. Ruppe