cppadvanced20 minutes

Implement a Thread-Safe Memoization Function in C++

Build a reusable templated function that memoizes results of expensive computations in a thread-safe manner using modern C++ features.

Challenge prompt

Implement a templated function named `memoize` that accepts a callable (function, lambda, or functor) and returns a new callable which caches the results of prior calls to improve performance on repeated inputs. The memoization cache should be thread-safe, allowing concurrent access from multiple threads without data races or undefined behavior. Your solution should support callables with one or more parameters of arbitrary types, and should use efficient synchronization mechanisms from the C++ Standard Library. Avoid global/static variables to ensure reusability in multiple contexts.

Guidance

  • Use templates to allow memoizing functions with different signatures and parameter types.
  • Use a suitable container such as `std::unordered_map` or `std::map` to store cached results keyed by the function arguments.
  • To allow multiple arguments and arbitrary types as keys, consider using `std::tuple` combined with a hash function.
  • Use synchronization primitives like `std::mutex` or `std::shared_mutex` to protect access to the cache for thread safety.

Hints

  • Provide a custom hash function or specialize `std::hash` for `std::tuple` if you use it as a key in an unordered map.
  • Consider using `std::lock_guard` or `std::shared_lock` for scoped locking.
  • Use perfect forwarding for the input parameters to preserve value categories.

Starter code

template<typename Func>
auto memoize(Func&& f) {
    // Your implementation here
}

Expected output

The returned callable caches results to quickly return cached values on repeated calls, and is safe for concurrent use (verified by testing with multi-threaded calls).

Core concepts

templatesthread safetymemoizationconcurrency primitives

Challenge a Friend

Send this duel to someone else and see if they can solve it.