title: When copying or moving std::function, can I update a lambda-captured this pointer?
body: <p>I have a class which holds a <code>std::function</code> as a member variable. The <code>std::function</code> returns a value which is usually determined from the lambda-captured 'this' pointer from a containing class. When I swap two items of the containing class, the <code>std::functions</code> are swapped, but their lambda-captured pointers aren't swapped, so the functions are now misaligned.</p>
  <pre><code>#include &lt;iostream&gt;
  #include &lt;functional&gt;
  
  
  class FunctionHolder
  {
  public:
      using F = std::function&lt;int()&gt;;
  
      FunctionHolder(const F&amp; f) : func(f) {}
  
      FunctionHolder(FunctionHolder&amp;&amp; other) noexcept :
          func(std::move(other.func))
      {}
  
      FunctionHolder&amp; operator= (FunctionHolder&amp;&amp; other) noexcept
      {
          if (&amp;other != this)
              func = std::move(other.func);
  
          return *this;
      }
      
      F func;
  };
  
  class TestClass
  {
  public:
      TestClass(const int i) :
          value(i),
          f([this]() { return value; })
      {}
  
      int getValue() const { return value; }
  
      void run() const { std::cout &lt;&lt; getValue() &lt;&lt; &quot; : &quot; &lt;&lt; std::invoke(f.func) &lt;&lt; '\n'; }
      
  private:
      FunctionHolder f;
      int value;
  };
  
  
  
  
  int main()
  {
      auto t1 = TestClass(1), t2 = TestClass(2);
  
      std::cout &lt;&lt; &quot;before swap&quot; &lt;&lt; '\n';
      t1.run();
      t2.run();
  
      std::swap(t1, t2);
  
      std::cout &lt;&lt; '\n' &lt;&lt; &quot;after swap&quot; &lt;&lt; '\n';
      t1.run();
      t2.run();
  }
  </code></pre>
  <p>This outputs:</p>
  <pre><code>before swap
  1 : 1
  2 : 2
  
  after swap
  2 : 1
  1 : 2
  </code></pre>
  <p>It makes sense why this would happen, since the <code>std::function</code> doesn't really know what is captured. I'm wondering if there is anything I can do about it? Is there a way to somehow update the pointers as well, or is there an alternative strategy I should consider?</p>