digitalmars.D.learn - template deduction
- Mafi (29/29) Aug 22 2010 Hey,
- bearophile (39/40) Aug 22 2010 You are doing it wrong. Such template tricks are not easy to get right, ...
- Mafi (6/42) Aug 23 2010 I see; I should use template magic. Oh, and I used Tuple the wrong way
- bearophile (7/9) Aug 22 2010 This was one problem, but maybe there are other ones:
Hey, I've written some caching template which should cache the return values. It looks like this: ////// template cached(F : R function(P), R, P...) { R cached(P p) { static R[Tuple!(P)] cache = []; R* pointer = Tuple!(P)(p) in cache; if(pointer !is null) { return *pointer; } else { cache[Tuple!(P)(p)] = F(p); return cache[Tuple!(P)(p)]; } } } ////// I am not able to instatiate ths template in any way. In my opinion there is enough information so that I can my template like this: ////// alias cached!(&func) cfunc; ////// But this doesn't work. It doesn't work the verbose way either. I've attached the whole test code so you can see if the error is somewhere else. Thanks for reading! Mafi PS: I used the verbose variant of template declaration because my old template signature didn't work with the short form. PPS: I'm usinng D2
Aug 22 2010
Mafi:I am not able to instatiate ths template in any way.You are doing it wrong. Such template tricks are not easy to get right, so probably the best thing you may do is to start from an empty program that works, and then keep adding to it, and keep it working, until you reach something good enough. If you write ten lines of code then later it's hard to make them work :-) This is an implementation that seems to work, but it's not nice, maybe you can improve it, I have had to use a delegate because I have found a forward reference problem (I am not sure if it's worth for Bugzilla): import std.stdio: writeln; import std.typecons: Tuple, tuple; import std.traits: ReturnType, ParameterTypeTuple; struct Memoize(alias F) { ReturnType!F opCall(ParameterTypeTuple!F args) { alias ReturnType!F ResultType; static ResultType[Tuple!(ParameterTypeTuple!F)] cache; auto ptr = tuple(args) in cache; if (ptr == null) { auto result = F(args); cache[tuple(args)] = result; return result; } else { return *ptr; } } } pure int fib(int n) { if (n < 2) return n; return fib(n - 1) + fib(n - 2); } void main() { pure int delegate(int n) cfib_impl; Memoize!cfib_impl cfib; cfib_impl = (int n) { if (n < 2) return n; return cfib(n - 1) + cfib(n - 2); }; enum int N = 40; writeln("fib(", N, ") = ", fib(N)); writeln("cfib(", N, ") = ", cfib(N)); } Bye, bearophile
Aug 22 2010
Am 22.08.2010 21:45, schrieb bearophile: (...)import std.stdio: writeln; import std.typecons: Tuple, tuple; import std.traits: ReturnType, ParameterTypeTuple; struct Memoize(alias F) { ReturnType!F opCall(ParameterTypeTuple!F args) { alias ReturnType!F ResultType; static ResultType[Tuple!(ParameterTypeTuple!F)] cache; auto ptr = tuple(args) in cache; if (ptr == null) { auto result = F(args); cache[tuple(args)] = result; return result; } else { return *ptr; } } } pure int fib(int n) { if (n< 2) return n; return fib(n - 1) + fib(n - 2); } void main() { pure int delegate(int n) cfib_impl; Memoize!cfib_impl cfib; cfib_impl = (int n) { if (n< 2) return n; return cfib(n - 1) + cfib(n - 2); }; enum int N = 40; writeln("fib(", N, ") = ", fib(N)); writeln("cfib(", N, ") = ", cfib(N)); } Bye, bearophileI see; I should use template magic. Oh, and I used Tuple the wrong way beacuse I've never used it before. Thanks Mafi
Aug 23 2010
but it's not nice, maybe you can improve it, I have had to use a delegate because I have found a forward reference problem (I am not sure if it's worth for Bugzilla):This was one problem, but maybe there are other ones: struct Foo(alias f) {} Foo!main baz; void main() {} I have added it to bug 4152. Bye, bearophile
Aug 22 2010