有时,当条件发生变化时,需要执行一些操作,下面是一个简单的类,用于跟踪上次调用的状态,并在状态更改时执行回调。
#include <functional>
#include <cassert>
/// 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<class...Args>
class Latch {
public:
Latch(std::function<bool(Args ...)> shouldLatch, std::function<void(Args...)> onLatch = nullptr, std::function<void(Args...)> 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&& ... args)
{
if (m_shouldLatch && m_isLatched != m_shouldLatch(std::forward<Args>(args)... ))
{
m_isLatched = !m_isLatched;
auto& call = (m_isLatched) ? m_onLatch : m_onUnlatch;
if (call) call(std::forward<Args>(args)...);
}
}
private:
bool m_isLatched = false;
std::function<bool(Args ...)> m_shouldLatch;
std::function<void(Args ...)> m_onLatch;
std::function<void(Args ...)> m_onUnlatch;
};
int main()
{
int onLatch = 0;
int onUnlatch = 0;
int latchVal = 1;
Latch<int> l1([&latchVal](auto val){return val == latchVal;},
[&onLatch](auto val){++onLatch;},
[&onUnlatch](auto val){++onUnlatch;});
assert(!l1);
l1.update(0);
assert(!l1);
assert(onLatch == 0 && onUnlatch == 0);
l1.update(1);
assert(l1.latched());
assert(onLatch == 1 && onUnlatch == 0);
l1.update(1);
assert(onLatch == 1 && onUnlatch == 0);
l1.update(0);
assert(onLatch == 1 && onUnlatch == 1);
Latch l2 = l1;
}这也是在https://www.godbolt.org/z/z4b934
谢谢你的意见
发布于 2020-10-23 21:00:17
在我看来,没有什么可改进的,除了:
std::move()您将按值将shouldLatch、onLatch和onUnlatch传递给构造函数,因此没有理由在成员初始化程序列表中使用std::move()。
https://codereview.stackexchange.com/questions/251059
复制相似问题