2

ですから、これについて考えれば考えるほど、その合法性は奇妙に思えます。memoizer ファンクターのインスタンスをそのコンストラクターに渡すと、コンパイラーは文句を言いません。memoizer テンプレートで 'f' をどのように読むべきですか? 同じ型宣言OutputT (&f) InputTを使用して、参照によって関数を参照できるようです。または、これは違法だと思いましたが、メンバー関数、つまりoperator()class のインスタンスへの参照memoizer<int,int>です。operator()代わりに f を「定義済みのものへの参照」と読むべきですか?

#include <map>
#include <iostream>

template<typename OutputT, typename InputT>
class memoizer
{
private:
    OutputT (&f) (InputT);
    std::map<InputT,OutputT> dat;

public:
    memoizer( OutputT (&f) ( InputT ) ) : f(f) { }

    OutputT operator()( InputT t )
    {
        if( dat.count(t)==0 )
            dat[t] = f(t);
        return dat[t];
    }
};

int fib( int n )
{
    if( n < 2 ) return 1;
    return fib( n-2 ) + fib( n-1 );
}

int main()
{
    memoizer<int,int> fib_memo( fib );
    memoizer<int,int> fib_memo_memo( fib_memo );    

    std::cout << fib( 12 ) << "\n";
    std::cout << fib_memo( 12 ) << "\n";
    std::cout << fib_memo_memo( 12 ) << "\n";
}

誤解しないでほしいのですが、機能してよかったです。まるで「魔法のよう」に思えます。前もって感謝します。

4

1 に答える 1

2

あなたは自分をだましています。メンバー変数に が含まfib_memo_memoれるメモライザーではありません。そこのイニシャライザは実際には暗黙のコピー コンストラクタを使用しているため、単なるコピーです。追加することで、これを自分で確認できますffib_memofib_memo_memofib_memo

memoizer(const memoizer &m) = delete;

次のようなエラーが発生し始めます

error: call to deleted constructor of 'memoizer<int, int>'
    memoizer<int,int> fib_memo_memo( fib_memo );
于 2012-09-06T02:08:13.440 に答える