Intrinsics, std.bind problems, list comphrensions, recursivity test
Tom S
h3r3tic at remove.mat.uni.torun.pl
Fri Aug 24 04:14:12 PDT 2007
bearophile wrote:
> import std.stdio, std.bind, std.traits, std.random;
>
> int randInt(int min, int max) {
> int k, n;
> n = (max - min) + 1;
> k = cast(int)(n * (rand() / (uint.max + 1.0)));
> return (k == n) ? k + min - 1 : k + min;
> }
>
> int randInt(int max) {
> int k, n;
> n = max + 1;
> k = cast(int)(n * (rand() / (uint.max + 1.0)));
> return (k == n) ? k - 1 : k;
> }
>
> void main() {
> // This line:
> // auto rnd = bind(&randInt, 100);
>
> // Raises:
> // ...\std\bind.d(395): static assert is false
Yup, because Bind extracts type info from the passed delegate /
function, and in this case it has two options. I'll try to see if I
could somehow make it 'guess', basing on the number of parameters, which
type to expect, but there might be problems with it. Anyway, the
solution is to tell it which function pointer to choose, by using a cast.
>
> // Line 394-395 of std.bind.d:
> // // make sure we'll copy all args the function is going to need
> // static assert (res >= minFuncArgs);
>
> auto rnd100 = bind(&randInt, 0, 99);
>
> writefln( typeid(typeof(rnd100)) , '\n');
> // Prints:
> // std.bind.BoundFunc!(int(*)(int min, int max),NullAlias,Tuple!(int,int) ).BoundFunc
bind() doesn't return a delegate, it returns a BoundFunc object. Access
the delegate by using .ptr(). Otherwise, opCall can be used on the
object, but traits doesn't work on it
> writefln(rnd100(), ' ', rnd100(), '\n'); // OK
>
> // This line:
> // ReturnType!(typeof(rnd100)) x;
>
> // Raises:
> // ...\std\traits.d(34): alias std.traits.ReturnType!(BoundFunc).ReturnType recursive alias declaration
>
> static if (is(rnd100 TyOut == return)) {
> TyOut x;
> writefln(typeid(typeof(x)));
> } else
> writefln("No return"); // Prints this
> }
>
> (In the end I have simply solved the problem without std.bind, defining a lambda function.)
And here's the solution with Bind:
// ----
import std.stdio, std.bind, std.traits, std.random;
int randInt(int min, int max) {
writefln(`rand1`);
int k, n;
n = (max - min) + 1;
k = cast(int)(n * (rand() / (uint.max + 1.0)));
return (k == n) ? k + min - 1 : k + min;
}
int randInt(int max) {
writefln(`rand2`);
int k, n;
n = max + 1;
k = cast(int)(n * (rand() / (uint.max + 1.0)));
return (k == n) ? k - 1 : k;
}
void main() {
// This line:
auto rnd = bind(cast(int function(int))&randInt, 100).ptr();
rnd();
auto rnd100 = bind(&randInt, 0, 99).ptr();
writefln( typeid(typeof(rnd100)) , '\n');
writefln(rnd100(), ' ', rnd100(), '\n'); // OK
ReturnType!(typeof(rnd100)) x;
writefln(typeid(typeof(x)));
}
// ----
Cheers!
--
Tomasz Stachowiak
http://h3.team0xf.com/
h3/h3r3tic on #D freenode
More information about the Digitalmars-d-learn
mailing list