【问题标题】:C++11 - How to use a priority_queue with a vector of shared pointers?C++11 - 如何使用带有共享指针向量的priority_queue?
【发布时间】:2015-10-06 02:24:40
【问题描述】:

我的班级中有一个priority queue,如下所示:

    class Foo
    {
    public:
        //public methods...
    private:
        std::priority_queue<Obj, std::vector<Obj>, object_less> foo_queue;

        //private methods and members...
    }

我一直在使用emplace() 方法在我的priority_queue 中插入对象,如下所示:

void Foo::add( ... ) {
    foo_queue.emplace(var1, var2);
}

这将调用Obj(var1,var2) 的构造函数并将其插入priority queue

但是现在,我需要从外部访问std::vector&lt;Obj&gt;。来自我的Obj 对象。

类似于创建Foo object,并更改位于priority_queue 上的对象内的成员:

Foo myFoo; // <-- this is where the priority_queue is!

Obj myObj(1); //Creating an object that has some member with value '1'

myFoo.add(myObj); //This will add the object to the priority_queue via emplace (actually it is creating a new object...and not using that one)

myObj.m_member = 2; //HERE WON'T WORK!!! And now I want to change some value on my Obj to '2'. It won't work, because the object that lives inside the priority_queue is different from this one!

所以,我在想:

  • 不要使用emplace 方法,而是使用push(可能推送不会创建新对象)
  • priority_queue 更改为,而不是让对象向量std::vector&lt;Obj&gt; 具有共享指针向量,因此我可以从外部访问位于priority_queue 内部的Obj。如上图。

问题:

你认为这是个好主意吗?我是 smart_pointers 的新手。我不知道是否有更简单的解决方案。

如何使用带有 shared_pointers 向量的 priority_queue? 有人知道我可以遵循的简单示例吗?

类似这样的:

std::priority_queue<std::shared_ptr<Obj>, std::vector<std::shared_ptr<Obj>>, object_less> foo_queue;

然后希望我可以执行:

Foo myFoo;
Obj myObj(1);
myFoo.add(myObj);
myObj.m_member = 2; //<--Now the m_member should be 2 inside the priority_queue.. is this "possible"?

【问题讨论】:

  • push 而不是 emplace 不会解决您的问题。 shared_ptr“有效”的解决方案,但它的设计很糟糕。为什么对象同时存在于类和优先级队列中?为什么全班不能排队呢?
  • 我创建了一个对象(Obj),然后我想将它插入到我的priority_queue中。像这样创建,以便其他模块将只使用一个简单的接口。

标签: c++ c++11 vector shared-ptr priority-queue


【解决方案1】:

拥有 shared_ptrs 的优先级队列并没有错。您需要注意的一件事是比较。 priority_queue 当然需要比较,默认情况下它使用operator &lt;。但是 shared_ptrs 上的该运算符比较指针本身而不是指向的对象。您需要将自定义比较器传递给对对象本身进行操作的优先级队列。幸运的是,您似乎已经在使用自定义比较器,因此如果您忘记这样做,编译器会向您大喊大叫(尽管错误消息可能非常晦涩难懂)。

另外一个警告:如果您修改对象的方式会影响其在优先级队列中的顺序,那么东西将会出错。通过priority_queue 接口执行此操作的唯一方法是从队列中删除元素,更改它,然后重新添加它。

【讨论】:

    猜你喜欢
    • 2019-07-06
    • 2021-12-26
    • 2021-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-03
    • 1970-01-01
    • 2018-10-09
    相关资源
    最近更新 更多