2012-10-01 4 views
6

クラス内でmemoize関数を使用する方法を理解できません。クラス内でstd.functional.memoizeを使用するにはどうすればよいですか?

import std.functional; 

class A { 
    int slowFunc(int a, int b) { 
     return 0; 
    } 

    alias memoize!slowFunc fastFunc; 
} 

void main() { 
    auto a = new A; 
    a.fastFunc(1,2); 
} 

コンパイルしようとするとき、これはエラーを与える:エラー:私はこの作品を作りに行くかどうメンバーslowFunc

にアクセスする必要「これを」?

+0

と 'alias memoize!(this.slowFunc)fastFunc;'? –

+0

コンパイル時に同じエラーが発生する – WelshDragon

答えて

6

実際にはまだサポートされていません。私たちは強化要求を提出することができます。ここに私の実験的実装があります:

import std.stdio; 
import std.traits; 
import std.typecons; 
import std.datetime; 

template isClassStruct(alias fun) 
{ 
    enum bool isClassStruct = (is(fun == class) || is(fun == struct)); 
} 

mixin template memoize(alias fun, uint maxSize = uint.max) 
    if (isClassStruct!(__traits(parent, fun))) 
{ 
    ReturnType!fun opCall(ParameterTypeTuple!fun args) 
    { 
     static ReturnType!fun[Tuple!(typeof(args))] memo; 
     auto t = tuple(args); 
     auto p = t in memo; 
     if (p) return *p; 
     static if (maxSize != uint.max) 
     { 
      if (memo.length >= maxSize) memo = null; 
     } 

     mixin("auto r = this." ~ __traits(identifier, fun) ~ "(args);"); 
     memo[t] = r; 
     return r; 
    }  
} 

class A 
{ 
    int slowFunc(int a, int b) 
    { 
     int result; 
     foreach (_; 0 .. 1024) 
     { 
      result += a; 
      result += b; 
     } 
     return result; 
    } 

    mixin memoize!slowFunc fastFunc; 
} 

enum CallCount = 2048; 

void main() 
{ 
    A a = new A; 

    auto sw1 = StopWatch(AutoStart.yes); 
    foreach (x; 0 .. CallCount) 
    { 
     a.slowFunc(100, 100); // 11232 usecs 
    } 
    sw1.stop(); 
    writeln(sw1.peek.usecs); 

    auto sw2 = StopWatch(AutoStart.yes); 
    foreach (x; 0 .. CallCount) 
    { 
     a.fastFunc(100, 100); // 302 usecs 
    } 
    sw2.stop(); 
    writeln(sw2.peek.usecs); 
} 

タイミングコメントは私のマシンのものです。 :)

+0

意味的に安全ではありません。メソッドは、内部クラス状態(例えば、クラスフィールド)を検索しなければならないため、メソッドは 'this'参照を必要とします。その状態がコール間で変化すると、ハッシュされた結果は更新されず、古い結果が返されます。しかし、たぶん正当な使用事例があります(@ pureメソッドが思い浮かぶようになります)。 Enhancement filed as:http://d.puremagic.com/issues/show_bug.cgi?id=8743 –

+0

内部ハッシュをクリアする方法がありますが、すべての呼び出しでブールチェックを行う必要があります。例えば:http://dpaste.dzfl.pl/abb6086f –

+0

それを見つけた:http://dpaste.dzfl.pl/4ba280c7 –

関連する問題