简体   繁体   English

std :: queue具有不同的容器类型,具体取决于运行时数据

[英]std::queue with different container type depending on runtime data

I have a class which needs to use a std::queue as an instance var to store some data. 我有一个需要使用std :: queue作为实例var来存储一些数据的类。 My problem is that std::queue either uses std::deque as container type by default or one needs to provide another container type at compile time. 我的问题是,默认情况下std :: queue要么使用std :: deque作为容器类型,要么需要在编译时提供另一种容器类型。 But which container I would like to use depends on some runtime data of the class user, therefore I can't specify it on compile time. 但是我想使用哪个容器取决于类用户的某些运行时数据,因此我不能在编译时指定它。 After instanciation of the std::queue and providing the proper container implementation I don't care anymore about the container itself, but only use the interface of std::queue. 在实例化std :: queue并提供正确的容器实现之后,我不再关心容器本身,而只使用std :: queue的接口。

The containers I would like to provide are std::deque or boost::circular_buffer and both store the same type of elements, it's only that one is used whenever the caller would like to store infinite amount of data and the circular _buffer if not. 我想提供的容器是std :: deque或boost :: circular_buffer,并且都存储相同类型的元素,只要调用方想存储无限量的数据,就使用一个容器,否则就使用循环_buffer。

The only way I found so far is a custom abstract base class acting as common interface with two derived implementations for the different std::queue instances. 到目前为止,我发现的唯一方法是使用自定义抽象基类作为通用接口,并具有针对不同std :: queue实例的两个派生实现。 But in that case I have to duplicate the interface of std::queue which is really annoying. 但是在那种情况下,我必须复制std :: queue的接口,这确实很烦人。

Is there any way to declare and instanciate a std::queue in such a way? 有没有办法以这种方式声明和实例化std :: queue? Something like "std::queue with unknown/runtime provided container". 类似于“带有未知/运行时提供的容器的std :: queue”。

Template parameters must be known at compile type. 模板参数必须在编译类型时已知。 You would not be able to change the underlying container of the queue at run time. 您将无法在运行时更改queue的基础容器。 What you could do is some sort of wrapper or union that combines the two types of queues together and then use one or the other at run time depending on the run time condition. 您可以做的是将两种类型的队列组合在一起的包装器或联合体,然后根据运行时条件在运行时使用一种或另一种。

If you do not expect to have a lot of instances of that class, then a very low-tech, simple, but ultimately working approach would be to simply add two different member variables to your class: a std::queue<T> and a std::queue<T, boost::circular_buffer<T>> . 如果您不希望该类有很多实例,那么技术含量低,简单但最终可行的方法是简单地向类中添加两个不同的成员变量: std::queue<T> 一个std::queue<T, boost::circular_buffer<T>> Then choose the appropriate container at run-time, when you instantiate the class. 然后,在实例化类时在运行时选择适当的容器。

This will cost you a few additional bytes per instance of your class, becaus there will be one unused empty container in each, but at the same time spare you from any difficulties or over-complicated code you might experience with unions, boost::variant , void* or similar things. 每个类实例将花费您几个额外的字节,因为每个实例中将有一个未使用的空容器,但是与此同时,您可以避免使用工会可能遇到的任何困难或代码过于复杂, boost::variantvoid*或类似内容。

Here is a complete example: 这是一个完整的示例:

#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();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM