I'm trying to write a class lazy<T>, the skeleton of which is as follows:
template<class T>
class lazy
{
public:
template<class F>
lazy(F fetcher) //Store fetcher somehow
{
}
T get()
{
if (!cache)
cache = fetch(); //Access fetcher from constructor in a type-safe way
return cache.get();
}
private:
optional<T> cache;
};
My problem is how to store / access the fetch function in a type safe way. The reason I titled this message how I did is because I see that shared_ptr does almost exactly the same thing with its deleter. But I'm still kind of new to the whole metaprogramming thing and having a little difficulty really getting my head around how it works. I guess there is some general "pattern" that applies in both of these cases as well as any other case where you want to store some value, the type of which is deduced by the constructor, and then later accessing that value in a type safe way. This message could probably have been equally well fitting in a general C++ forum, but since this is a problem that seems to arise really frequently in boost and other code using heavy templates, I guess I'm in pretty good company here as well.
The following seems close to a solution:
template<class T> class lazy_impl_base
{
virtual T fetch() = 0;
};
template<class T, class F> class lazy_impl : public lazy_impl_base<T>
{
// etc
};
and then storing a lazy_impl_base<T>* in lazy<T>. But there are strange compiler warnings, and I fear I will encounter subtle errors when I attempt to use it with functors, binders, and other non trivial "functions".
Can anyone offer some guidance here? Maybe a quick high level overview of how shared_ptr and other boost libraries solve this problem, or even an implementation of lazy that works :P