Memoization via template
I would change memoized to work with a functor type and use a traits approach to deduce the return type and the argument type.

template &lt;typename Functor&gt;
typename Functor::R memoized(typename Functor::T in) {
   using T = typename Functor::T;
   using R = typename Functor::R;

   static std::map&lt;T,R&gt; memo;
   typename std::map&lt;T,R&gt;::iterator found = memo.find(in);
   if (found != memo.end()) { return found-&gt;second; }  
   std::cout &lt;&lt; "not found" &lt;&lt; std::endl; // only for demo
   R res = Functor()(in);
   memo[in] = res;
   return res;
}

struct Test1
{
   using T = double;
   using R = double;
   R operator()(T x) { return x*x; }
};

struct Test2
{
   using T = double;
   using R = double;
   R operator()(T x) { return x; }
};


My rationale for using a functor is that it simplifies user code.

int main() {
    std::cout &lt;&lt; memoized&lt;Test1&gt;(1) &lt;&lt; std::endl;
    std::cout &lt;&lt; memoized&lt;Test1&gt;(1) &lt;&lt; std::endl;
    std::cout &lt;&lt; memoized&lt;Test1&gt;(1) &lt;&lt; std::endl;
    std::cout &lt;&lt; std::endl;
    std::cout &lt;&lt; memoized&lt;Test2&gt;(1) &lt;&lt; std::endl;
    std::cout &lt;&lt; memoized&lt;Test2&gt;(1) &lt;&lt; std::endl;
    std::cout &lt;&lt; memoized&lt;Test2&gt;(1) &lt;&lt; std::endl;

    return 0;
}