Understanding Safety of Function Pointers vs. Addresses of Functions

jmh530 via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sun Jul 12 09:34:14 PDT 2015


On Wednesday, 8 July 2015 at 18:31:00 UTC, Steven Schveighoffer 
wrote:
>
> You can use a function lambda:
>
> auto fp = (real a) => cos(a);
>
> Note, I had to put (real a) even though I would have expected 
> "a => cos(a)" to work.
>
> -Steve

I've been playing around with this a little more. I wrote this 
function to encapsulate a simple operation on arrays.

U array_fun(T, U)(T fp, U x)
	if (isFunctionPointer!(T) && isArray!(U))
{
	return x.map!(a => fp(a)).array;
}

Then I wrote a cos function that calls it on using a function 
pointer.

T cos(T : U[], U)(T x)
	if (isArray!(T))
{
	auto fp = (U a) => cos(a);
	return array_fun(fp, x);
}

This seems to work just fine, but for some reason this only seems 
to work when I import std.math : cos. It doesn't work when I just 
do import std.math. Bug?

Nevertheless, if I want to implement it for another function, 
then I have to write it all over again. So I wrote a mixin that 
would encapsulate that idea (I put in the \n, \t for formatting 
purposes because I like to be able to writeln it out and see that 
it matches the original).

template mixin_builder(string function_name)
{
	const char[] mixin_builder =
		"T " ~ function_name ~ "(T : U[], U)(T x)\n" ~
			"\tif (isArray!(T))\n" ~
		"{\n" ~
			"\tauto fp = (U a) => " ~ function_name ~ "(a);\n" ~
			"\treturn array_fun(fp, x);\n" ~
		"}";
}

Then I can just call
mixin(mixin_builder!("cos"));
mixin(mixin_builder!("sin"));

While it works, it feels a bit hackish. I'm not sure I can think 
of a generic way to do this without mixins.


More information about the Digitalmars-d-learn mailing list