std::根据运行时数据使用不同的容器类型排队

std::queue with different container type depending on runtime data

本文关键字:类型 排队 运行时 数据 std      更新时间:2023-10-16

我有一个类需要使用 std::queue 作为实例 var 来存储一些数据。我的问题是 std::queue 要么默认使用 std::d eque 作为容器类型,要么需要在编译时提供另一种容器类型。但是我想使用哪个容器取决于类用户的一些运行时数据,因此我无法在编译时指定它。在 std::queue 实例化并提供正确的容器实现之后,我不再关心容器本身,而只使用 std::queue 的接口。

我想提供的容器是 std::d eque 或 boost::circular_buffer 并且都存储相同类型的元素,只是在调用者想要存储无限量数据时使用一个元素,如果没有,则使用循环_buffer。

到目前为止,我发现的唯一方法是使用自定义抽象基类作为公共接口,其中包含不同 std::queue 实例的两个派生实现。但是在这种情况下,我必须复制std::queue的界面,这真的很烦人。

有没有办法以这种方式声明和实例化 std::queue?类似于"std::queue,未知/运行时提供的容器"。

模板参数必须在编译类型中知道。 您将无法在运行时更改queue的基础容器。 您可以做的是某种包装器或联合,将两种类型的队列组合在一起,然后在运行时根据运行时条件使用其中一种。

如果您不希望该类有很多实例,那么一种技术含量非常低、简单但最终可行的方法是简单地将两个不同的成员变量添加到您的类中:std::queue<T>std::queue<T, boost::circular_buffer<T>>。然后在运行时实例化类时选择适当的容器。

这将花费您每个类实例的一些额外字节,因为每个实例中都有一个未使用的空容器,但同时使您免于在联合、boost::variantvoid*或类似方面可能遇到的任何困难或过于复杂的代码。

下面是一个完整的示例:

#include <boost/circular_buffer.hpp>
#include <queue>
#include <deque>
#include <iostream>
class YourClass
{
public:
    YourClass(bool needs_infinite_amount_of_data) :
        needs_infinite_amount_of_data(needs_infinite_amount_of_data),
        queue(),
        queue_with_circular_buffer(boost::circular_buffer<int>(needs_infinite_amount_of_data ? 0 : 100))
    {
    }
    void Operation()
    {
        if (needs_infinite_amount_of_data)
        {
            Operation(queue);
        }
        else
        {
            Operation(queue_with_circular_buffer);
        }
    }
private:
    template <class Container>
    static void Operation(Container& container)
    {
        container.push(1);
        std::cout << container.front() << "n";
    }
    bool needs_infinite_amount_of_data;
    std::queue<int> queue;
    std::queue<int, boost::circular_buffer<int>> queue_with_circular_buffer;
};
int main()
{
    YourClass obj(false);
    obj.Operation();
}