我围绕FreeRTOS定时器API构建了一个C++ Package 器。我的类静态分配定时器控制块,该控制块由FreeRTOS线程在后台操作。这意味着如果我移动或复制此对象,控制块也将被移动/复制,但线程不会注意到这一点。因此,我认为该对象不可复制和不可移动。
以下是大纲:
#include <cstdint>
#include <concepts>
template <std::invocable Cb>
class timer
{
public:
timer() = default;
timer(Cb cb, TickType_t timer_period, bool auto_reload = false)
: cb_{ cb }
{
xTimerCreateStatic("timer", timer_period, auto_reload, static_cast<void*>(this), &timer::timer_expired_cb, &buf_);
}
timer(const timer&) = delete;
timer(timer&&) = delete;
auto operator=(const timer&) = delete;
auto operator=(timer&&) = delete;
// ...
private:
Cb cb_;
TimerHandle_t handle_;
StaticTimer_t buf_;
};
现在我想把多个这个定时器对象推入一个C++容器,当对象进入或离开容器时,我可以动态地扩展或收缩容器。有没有一个stdlib容器不要求对象是可移动或可复制的,但仍然提供所有功能?
1条答案
按热度按时间vxbzzdmp1#
我看到四个基本选项:
std::list<timer>
:这可能是非常罕见的情况之一,此时使用std::list
是最佳选择。插入到列表中必须通过一个emplace成员函数来完成,因为你不能在一个已经存在的对象中移动。std::vector<std::unique_ptr<timer>>
:如果timer
对象的构造与将它们保存在容器中没有直接关系。这样做的缺点是访问和删除条目比std::list
稍微多一些。但是你的timer
工厂不需要知道你打算如何存储对象。std::set<timer>
:你说你有新的对象到达和离开。如果你有很多对象,也许你想避免find
把它们放在一个线性容器中。std::set
也没有重新分配,并为你提供了一个很好的界面来查找和擦除对象。但很明显,它比其他两个建议有更多的开销。std::array<std::optional<timer>, N>
:如果你知道在运行时你能看到的最大计时器数N,考虑一个固定大小的数组,其中包含可选项。它没有指针间接寻址,但在搜索一个项时可能会有很多分支。