Search code examples
c++pointersc++11strategy-patternstd-function

How to implement strategy pattern in C++ with std::function


I'm reasing about the best way to implement the strategy pattern in C++. Up to now, I've always used the standard way, where the context has a pointer to the base strategy class as follows:

 class AbstractStrategy{
 public:
     virtual void exec() = 0;
 }
 class ConcreteStrategyA{
 public:
     void exec();
 }
 class ConcreteStrategyB{
 public:
     void exec();
 }

 class Context{
 public:
     Context(AbstractStrategy* strategy):strategy_(strategy){}
     ~Context(){
          delete strategy;
       }
      void run(){
           strategy->exec();
      }
 private:
     AbstractStrategy* strategy_;

Since having pointers to objects can result in bad behavior, I was looking for a safer way to implement this pattern and I found this question where std::function are proposed as a better way to handle this pattern.

Could someone please explain better how std::function works, maybe with an example with the strategy pattern?


Solution

  • Note that single-method objects are isomorphic to functions, and strategies are just single-method objects.

    So basically, you get rid of all your classes, and you just use std::function<void()> instead:

    class Context {
    public:
        template<typename F>
        explicit Context(F strategy) : strategy(std::move(strategy)) { }
    
        void run() { strategy(); }
    
    private:
        std::function<void()> strategy;
    };
    

    Then you can pass any callable to the constructor of Context:

    Context ctx([] { std::cout << "Hello, world!\n"; });
    ctx.run();