So, the more I think about this the weirder its legality seems. When I pass my an instance of my memoizer functor into its constructor, the compiler doesn’t complain. How should ‘f’ be read in the memoizer template? It seems that with the same type declaration OutputT (&f) InputT it can refer to a function by reference, or–and I thought this was illegal–a reference to a member function, namely operator() of an instance of the class memoizer<int,int>. Should f instead be read as ‘a reference to something with an operator() defined?’
#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";
}
I mean, don’t get me wrong: I’m glad it works, it just seems kind of ‘magical.’ Thanks in advance.
You’re tricking yourself.
fib_memo_memois not a memoizer whosefmember variable containsfib_memo. Your initializer there is actually using the implicit copy constructor, sofib_memo_memois just a copy offib_memo. You can verify this yourself by addingYou’ll start getting errors like