是否可以定义一个队列列表,其中每个队列可以属于不同类型?

时间:2019-07-09 23:11:59

标签: c++ data-structures

我正在尝试定义一个类,其中的主要元素是队列列表。

问题在于每个队列可以具有不同的类型。

这是我想要得到的例子。如果我们定义这些队列:

queue1 (type int)    = {5,7,3,4,5}
queue2 (type string) = {"Sam","Peter"}
queue3 (type string) = {"January","February","March"}
queue4 (type int)    = {10}

然后,我希望能够创建如下对象:

object1.list_of_queues = {queue1,queue2}
object2.list_of_queues = {queue2,queue3,queue4}

所有这些都基于相同的类。

我能够创建“队列列表”类型,但它们都共享相同的类型:

typedef std::queue<std::string> queue_type; //queue of strings
typedef std::list<queue_type> list_type;    //list of queues of (only) strings

有没有不使用列表来避免这种类型混合的解决方案?我正在考虑将队列封装为新的定义类型。或创建一个指针列表,每个指针都指向正确的队列,但是我不知道这是否可行。

提前谢谢!

3 个答案:

答案 0 :(得分:2)

  

是否可以定义一个队列列表,其中每个队列可以属于不同类型?

不直接。

一种元素类型的std::queue与另一种元素类型的队列不同。 std::list是同质容器:所有元素都具有相同的类型。

您可以做的是拥有类型清除包装器的列表或队列,例如std::variantstd::any,其中可以包含来自相应限制或无限选择的类型的对象。

答案 1 :(得分:1)

根据您的评论,我怀疑您想这样做:

#include <iostream>
#include <string>
#include <list>
#include <memory>

class Shape
{
public:
    virtual double area() const = 0;
};


class Circle : public Shape
{
    double radius;
public:
    Circle(const double r) : radius(r) {}
    double area() const {
        return 3.1416 * radius * radius;
    }
};


class Square : public Shape
{
    double side;
public:
    Square(const double s) : side(s) {}
    double area() const {
        return side * side;
    }
};


int main()
{
    std::list<std::unique_ptr<Shape>> my_list;
    my_list.push_back(std::make_unique<Circle>(2.0));
    my_list.push_back(std::make_unique<Square>(4.0));

    for(const auto& el : my_list)
        std::cout << el->area() << std::endl;
}

使用多态性/继承性创建Shape类型的对象的地方。然后,Im使用该父对象的列表作为pointer,因此可以创建不同的子元素,例如CirlceSquare

答案 2 :(得分:1)

是的,有很多方法可以做到这一点。该实用程序同时运行时和编译时多态。我最喜欢的实用程序有以下几种。 像伪代码这样的C ++如下:

#include <typeinfo>

namespace dynamics {

class AnyBase {
     virtual const type_info& getTypeInfo();
     virtual ~AnyBase()
}

template<typename T>
class DynamicAny : public AnyBase {
     type_info typekind;
     T val;

     template<typename T>
     DynamicAny(const T& t) : typekind(typeof(T)), val(t) {}

     //... usual move/copy constructors/operators follow

     //conversion operators
     inline operator T&() {
          return val;
     }
     inline operator const T&() const {
          return val;
     }

     //possibly comparison operators with const T& too...

     //virtual call for type information for this type
     const type_info& getTypeInfo() {
           return typekind;
     }
}

}

然后,您可以在引导程序或队列中包含任何std::unique_ptr<AnyBase>或与此相关的任何数据结构。但是为它分配所需类型的DynamicAny<T>。然后,当您从该数据结构中取出它时,只需在getTypeInfo()上调用AnyBase即可确定将其投射到哪个DynamicAny<T>上。 有关更多详细信息,请参见type_infohttp://www.cplusplus.com/reference/typeinfo/type_info/

您也可以使用std::any做类似的事情。 https://en.cppreference.com/w/cpp/utility/any 仅从c ++ 17开始。

typedef std::queue<std::unique_ptr<AnyBase>> queue_type; //queue of unique_ptr of DynamicAny<T>
typedef std::list<queue_type> list_type;    //list of queues of (only) strings