c++ - FIFO 类型的容器 - 哪种 STL 容器最合适,为什么?

标签 c++ stl containers

我最近的任务是实现一个缓冲区,它将被日志类用作临时存储。日志记录类本身是一个单例,并且使用了观察者监听器模式。您可以预期使用此类记录数以千计的消息。

现在问题出在这里:

我们有一个用于调试目的的跟踪日志记录选项。启用此选项后,消息计数/秒呈指数增长。在发布代码中禁用跟踪日志记录,但是可以存储固定数量消息的缓冲区,例如10000 被转储到日志中 IF 发生错误,以便开发人员可以确定问题的根源。

如果缓冲区已满,则最旧的消息将被删除,以便为最新消息腾出空间。

void Log::storeToBuffer(const LogType_E & type_in, const LogDomain_E & domain_in,const int & id_in, const char * msg_in)
{
    if(this->myEnableTraceBuffer)
    {
        if(static_cast<std::list<Message> * >(this->myRingBuffer)->size() < this->myRingBufferMaxSize)
        {
            static_cast<std::list<Message> * >(this->myRingBuffer)->push_back(Message(type_in, domain_in, id_in, msg_in));
        }
        else
        {
            //buffer full so remove oldest element and add new
            if(static_cast<std::list<Message> * >(this->myRingBuffer)->size() > 0) static_cast<std::list<Message> * >(this->myRingBuffer)->pop_front();
            static_cast<std::list<Message> * >(this->myRingBuffer)->push_back(Message(type_in, domain_in, id_in, msg_in));
        }
    }
}

我用 std::list 实现了这个,非常简单地使用 push_back/pop_front 来利用恒定的删除/插入执行时间。 (不要要求无效类型转换,不是我的决定)。

但是由于缓冲区大小是固定的,并且在对象的生命周期内不太可能改变,也许具有显式索引操作的 vector 更合适?例如,可以有两个 indeces , start/current 都从位置 0 开始。当 vector 已满并且我们添加一些东西 start 移动到位置 1 和 current 移动到位置 0,因此在打印结果时我们有正确的顺序。

也许另一个STL容器更适合这种东西?

感谢您耐心阅读这长长的文字墙。我在这里回答任何问题。

最佳答案

std::deque 可以在开头或结尾高效地插入或删除,使其成为一个出色的缓冲区结构。它可以用作 std::queue 的模板类型,这将非常适合您的应用程序 - 只需在每次执行 push 时检查队列的大小,并且pop 如果大小超过最大值。

关于c++ - FIFO 类型的容器 - 哪种 STL 容器最合适,为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8015337/

相关文章:

c++ - C++ 中的写时复制指针对象

c++ - 如何仅对 std::vector 中的子集进行排序?

Docker 容器未正确使用 CPU

c++ - 为什么我们有 std::string::npos 但没有 std::vector::npos?

windows - 在 server core 2019ltsc 容器镜像中添加字体

c++ - 卸载注入(inject)的 DLL

c# - 如何识别某个值是否在 C++ 的枚举类型中定义?

c++ - 具有不同数据类型的 std::move()

c++ - 创建一个不可复制的 STL 迭代器是个好主意吗?

c++ - map<string1, map<string2, map<string3, string>>> 是否比将字符串连接到 map<string1string2string3, string> 慢?