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

C++ std::根据运行时数据使用不同容器类型的队列,c++,boost,stl,C++,Boost,Stl,我有一个类需要使用std::queue作为实例变量来存储一些数据。我的问题是,std::queue默认使用std::deque作为容器类型,或者需要在编译时提供另一个容器类型。但我想使用哪个容器取决于类用户的一些运行时数据,所以我不能在编译时指定它。在实例化std::queue并提供适当的容器实现之后,我不再关心容器本身,而只使用std::queue的接口 我想提供的容器是std::deque或boost::circular\u buffer,它们都存储相同类型的元素,只是调用方希望存储无限量的

我有一个类需要使用std::queue作为实例变量来存储一些数据。我的问题是,std::queue默认使用std::deque作为容器类型,或者需要在编译时提供另一个容器类型。但我想使用哪个容器取决于类用户的一些运行时数据,所以我不能在编译时指定它。在实例化std::queue并提供适当的容器实现之后,我不再关心容器本身,而只使用std::queue的接口

我想提供的容器是std::deque或boost::circular\u buffer,它们都存储相同类型的元素,只是调用方希望存储无限量的数据时使用一个容器,如果不需要,则使用circular\u buffer

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


有没有办法以这种方式声明和实例化std::queue?类似于“std::queue with unknown/runtime-provided container”。

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

如果您不希望有大量该类的实例,那么一个非常低技术、简单的,但最终的工作方法是简单地向类中添加两个不同的成员变量:一个
std::queue
和一个
std::queue
。然后在实例化类时,在运行时选择适当的容器

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

下面是一个完整的示例:

#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();
}
#包括
#包括
#包括
#包括
你的班级
{
公众:
YourClass(布尔需要无限量的数据):
需要无限量的数据(需要无限量的数据),
队列(),
使用循环缓冲区排队(boost::循环缓冲区(需要无限量的数据?0:100))
{
}
无效操作()
{
if(需要无限量的数据)
{
操作(队列);
}
其他的
{
操作(带循环缓冲区的队列);
}
}
私人:
模板
静态无效操作(容器和容器)
{
容器。推(1);

std::我自己能想到一些关于这一点的东西吗,但这难道不意味着我需要一个包装器来检查我访问容器的每个方法所使用的容器吗?就像你的两个操作方法一样……我没有得到像container&getContainer()这样的东西使用模板工作。@ThorstenSchöning:是的,你需要那个包装器。但在任何情况下你都需要它。它可能在形式或语法上有所不同,但每个成员函数都必须在运行时决定使用哪个容器这一事实是无法回避的。没错,但我更喜欢用重复的std::queu创建我自己的小抽象类e接口,并提供它的两个具体实现,使用类的CTOR可以选择。这样,我只有一个地方需要记住创建正确的std::queue实例,而其他方法则针对我的抽象类。所有这些“if…else”都是我试图避免的。