I had an idea for a general cache, based on the idea that caches are
essentially trying to avoid re-calling expensive functions with the
same parameters as last time. So typically you build a cache key from
the params, put it in a map, etc. But what if we did things slightly
differently...
template <typename T>
struct cache
{
typedef boost::function< T () > retriever_function;
typedef std::map map;
map m;
T retrieve(retriever_function retriever)
{
map::iterator it = m.find(retriever);
if (it != m.end())
{
return it->second;
}
else
{
T t = retriever();
m[retriever] = t;
return t;
}
}
};
Basically, instead of building a key from the params, build a key from
the params + the function that takes the params. Then, as a bonus,
you don't need to worry about packing/unpacking the params - just let
bind() do that for you! The other bonus is that you can cache things
that may be created via different methonds.
So what's the problem?
The problem is that boost::function and boost::bind don't have
operator<(), so you can't put a boost::function in a map. :-(
(actually it appears boost::bind does have an operator<, but it
doesn't do what I want - it actually bind's the operator< into a
function!)
Any advice? Any chance boost::function might gain a < operator? (One
that compared the underlying function and the params, possibly handled
different numbe of params, etc - although I could live with requiring
all the param types to be the same. ie basically boost::function
would pass most of the work off to the function object (ie bind))
Do I instead need to use tuples and pack/unpack the params myself (and
write overloads for 0 to n params, handle return_type messes, etc etc
etc )?
- Tony