Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8748509
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 13, 20262026-06-13T12:32:12+00:00 2026-06-13T12:32:12+00:00

Suppose I have a calculator class that implements the Strategy Pattern using std::function objects

  • 0

Suppose I have a calculator class that implements the Strategy Pattern using std::function objects as follows (see Scott Meyers, Effective C++: 55 Specific Ways to Improve Your Programs and Designs):

class Calculator
{
public:
  ...
  std::vector<double> Calculate(double x, double y)
  {
     std::vector<double> res;
     for(const Function& f : functions)
        res.push_back(f(x,y));
     return res;
  }

private:
  std::vector<Function> functions;
};

where

typedef std::function<double(double,double)> Function;

Here is the problem I am facing: suppose functions f and g, both of type Function, perform expensive and identical calculations internally to get the final result. In order to improve efficiency, one could wrap all the common data in a struct, compute it once and provide to them as an argument. However, this design has several flaws. For example, this would cause a change in the signature of Function, which can result in unnecessary arguments being passed to some function implementations. Moreover, these common and internal data are no longer hidden from other components in the code, which can harm code simplicity.

I would like to discuss the following optimization strategy: implement a class CacheFG that:

  1. Define a Update method that calculates its internal data with a given pair of doubles x and y; and
  2. Define a Check method to determine if its current internal data was calculated with a given pair of doubles x and y.

What one could do then is to make f and g to share a common instance of the class CacheFG, which could be done using the std::shared_ptr construct. So, below would be the creation of f and g functions using auxiliary functions f_aux and g_aux.

double f_aux(double x, double y, const std::shared_ptr<CacheFG>& cache)
{
   if(not cache->Check(x,y))
      cache->Update(x,y);
   ...
}

std::shared_ptr<CacheFG> cache;
Function f = std::bind(f_aux, _1, _2, cache);
Function g = std::bind(g_aux, _1, _2, cache);

My questions are: (1) is this a safe approach for optimization? (2) is there a better approach for solving this problem?

Edit: After a few answers, I found out that my intention here is to implement a memoization technique in C++. I remark that only the last calculated state is enough for my purposes.


Thanks to DeadMG, I will now write here just an improvement over his approach. His idea consists of using a memoization technique with variadic templates. I just offer a slight modification, where I use the construct std::decay<Args>::type to ensure the definition of a tuple with non-reference types only. Otherwise, functions with const-reference arguments would cause compilation errors.

template<typename Ret, typename... Args>
std::function<Ret(Args...)> MemoizeLast(std::function<Ret(Args...)> f)
{
    std::tuple<typename std::decay<Args>::type...> cache;
    Ret result = Ret();
    return [=](Args... args) mutable -> Ret
    {
        if(std::tie(args...) == cache)
            return Ret(result);
        cache = std::make_tuple(args...);
        return result = f(args...);
    };
}

In order to prevent the move of result, a copy of it is returned (return Ret(result)) when the provided args is the one cached.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-13T12:32:13+00:00Added an answer on June 13, 2026 at 12:32 pm

    Why create your own class? There’s no need for you to fail to re-create the interface of unordered_map. This functionality can be added as a re-usable algorithm based on std::function and std::unordered_map. It’s been a while since I worked with variadic templates, but I hope you get the idea.

    template<typename Ret, typename... Args> 
    std::function<Ret(Args...)> memoize(std::function<Ret(Args...)> t) {
        std::unordered_map<std::tuple<Args...>, Ret> cache;
        return [=](Args... a) mutable -> Ret {
            if (cache.find(std::make_tuple(a...)) != cache.end())
                return cache[std::make_tuple(a...)];
            else
                return cache[std::make_tuple(a...)] = t(a...);
        };
    }
    

    I don’t recall, offhand, whether std::hash natively supports tuples. If not, you might need to add it, or use std::map which does natively support them.

    Edit: Hmm, I didn’t notice that you wanted to share the cache. Well, this shouldn’t be too difficult a problem, just stick an unordered_map member in Calculator and pass it in by reference, but the semantics of doing so seem a bit… odd.

    Edit again: Just the most recent value? Even simpler.

    template<typename Ret, typename... Args> 
    std::function<Ret(Args...)> memoize_last(std::function<Ret(Args...)> t) {
        std::tuple<Args...> cache;
        Ret result;
        return [=](Args... a) mutable -> Ret {
            if (std::tie(a...) == cache)
                return result;
            cache = std::make_tuple(a...);
            return result = t(a...);
        };
    }
    

    If you want to share between several Functions, then the alteration is the same- just declare it in the class and pass in as reference.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

Suppose I have a static method of my class that returns an object of
Suppose I have a class Baz that inherits from classes Foo and Bar ,
Suppose that I have the following mapping with a formula property: <class name=Planet table=planets>
Suppose i have a javascript <script language=javascript> var Calculator =function ADD(int x,int y) {
Suppose I have a simple class that Adds: public class Multiply { public int
Suppose I have simple class Order, that have a TotalPrice calculated property, which can
Suppose i have a function that returns an important result and several unimportant results.
Suppose that I have code as below: $('#dateNaissance').datepicker({ onSelect:function(date){ var today=new Date(); console.log(today.getTime()); console.log(new
Suppose we have a class named Calculator . There's a class method in it,
suppose i have a .on() function wherein i select multiple ids $(#i, #am, #your,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.