On 02/27/2017 10:52 AM, Bastiaan Veelo wrote:
On Monday, 27 February 2017 at 02:02:57 UTC, ag0aep6g wrote:
[...]
enum fptr(alias f) = &f;
(This is still a bit magical to me: it this a shorthand for a template?)

Yes, it's short for this:

template fptr(alias f) { enum fptr = &f; }

"addrOf" is probably a better name for this. It's not restricted to functions.

Can the following be made to work?

int one(int) {return 1;}
[...]
int one(string) {return 0;} // How to ignore this?

int[8] values;

template eval_all(funcs...)
{
    void eval_all(int val)
    {
[...]
        //enum fptr(alias f) = &f;          // Error: cannot infer type
from
                                            // overloaded function
symbol & one
        enum fptr(alias int f(int)) = &f;   // ditto.

Aside: That funky, C-like syntax surprised me. I guess that's a function type as opposed to a function pointer type, which would be `alias int function(int) f`. That distinction always trips me up.

        enum fptrs = staticMap!(fptr, funcs);
        auto r = only(fptrs);

        foreach (i, f; parallel(r))
            values[i] = f(val);
    }
}

You can generate wrapper functions that have no overloads:

----
static int wrap(alias f)(int arg) { return f(arg); }
enum addrOf(alias f) = &f;
enum fptrs = staticMap!(addrOf, staticMap!(wrap, funcs));
/* ... r and foreach as before ... */
----

This also unifies the signatures in other ways. For example, you can have a function that takes a `long` instead of an int.

Of course, if you passed the functions at run time, and not in a template parameter, the code would be much shorter:

----
void eval_all(int val, int function(int)[] funcs ...)
{
    import std.parallelism;

    foreach (i, f; parallel(funcs))
        values[i] = f(val);
}
void main()
{
    eval_all(42, &one, &two, &three, &four, &five, &six, &seven,
        &eight);
    foreach(i, val; values)
        assert(val == i + 1);
}
----

One little disadvantage of this is that the signatures have to match exactly. Overloads are fine, but you can't have a function with a `long` parameter. But that's really minor, and can be handled at the call site.

I think I'd prefer this over the template version. You have to make a run-time list of the functions anyway, for `parallel`, so the template stuff just seems to add complexity.

Reply via email to