Simple Boolean "Latch" with state Sometimes you need to do things when a condition changes, here is a simple class to keep track of the state of the last call and execute callbacks when the state changes.

#include &lt;functional&gt;
#include &lt;cassert&gt;


/// latch is a class that contains of a test function and a couple of callbacks, when the return
/// value of the test function changes the approrpiate callback gets called, as long as the return
/// value of the test function stays the same no callbacks will be called. Callbacks may be nullptr
template&lt;class...Args&gt;
class Latch {
public:
    Latch(std::function&lt;bool(Args ...)&gt; shouldLatch, std::function&lt;void(Args...)&gt; onLatch = nullptr, std::function&lt;void(Args...)&gt; onUnlatch = nullptr) :
                m_shouldLatch(std::move(shouldLatch)),
                m_onLatch(std::move(onLatch)),
                m_onUnlatch(std::move(onUnlatch)) {}

    bool latched() const noexcept { return m_isLatched; }
    
    explicit operator bool() const noexcept { return m_isLatched; }

    void update(Args&amp;&amp; ... args)
    {
        if (m_shouldLatch &amp;&amp; m_isLatched != m_shouldLatch(std::forward&lt;Args&gt;(args)... ))
        {
            m_isLatched = !m_isLatched;
            auto&amp; call = (m_isLatched) ?  m_onLatch : m_onUnlatch;
            if (call) call(std::forward&lt;Args&gt;(args)...);
        }
    }


private:
    bool m_isLatched = false;
    std::function&lt;bool(Args ...)&gt; m_shouldLatch;
    std::function&lt;void(Args ...)&gt; m_onLatch;
    std::function&lt;void(Args ...)&gt; m_onUnlatch;
};

int main() 
{
    int onLatch = 0;
    int onUnlatch = 0;
    int latchVal = 1;


    Latch&lt;int&gt; l1([&amp;latchVal](auto val){return val == latchVal;},
                  [&amp;onLatch](auto val){++onLatch;},
                  [&amp;onUnlatch](auto val){++onUnlatch;});
    assert(!l1);
    l1.update(0);
    assert(!l1);
    assert(onLatch == 0 &amp;&amp; onUnlatch == 0);
    l1.update(1);
    assert(l1.latched());   
    assert(onLatch == 1 &amp;&amp; onUnlatch == 0);
    l1.update(1);
    assert(onLatch == 1 &amp;&amp; onUnlatch == 0);
    l1.update(0);
    assert(onLatch == 1 &amp;&amp; onUnlatch == 1);

    Latch l2 = l1;
}

This is also at https://www.godbolt.org/z/z4b934
Thanks for the input
There is not much to improve in my opinion, except:
Unnecessary use of std::move()
You are passing shouldLatch, onLatch and onUnlatch by value to the constructor, so there is no reason to use std::move() in the member initializer list.