简体   繁体   English

如何从shared_ptr向量中的位置移除对象并将其推回末尾?

[英]How to remove an object from a position in a vector of shared_ptr and push back to the end?

I want to create a method where I search for a specific object (this case a Bar object), inside a vector . 我想创建一个方法,在其中搜索vector内的特定对象(本例为Bar对象)。 When I find that object bar in the vector , I should push_back that piece to the end of the vector . 当我在vector找到该对象栏时,应将该块push_backvector的末尾。

I have 3 questions regarding this implementation... but I don't know if there is an easier way to do this. 关于此实现,我有3个问题...但是我不知道是否有更简单的方法来实现。

This is my implementation: 这是我的实现:

std::vector<std::shared_ptr<Bar>> mBarVector;

//(...)

void Foo::pushBack(Bar& bar)
{
    for (auto& b : mBarVector)
    {
        if(*b == bar) // ERROR [1]
        {
            //mBarVector.erase(?) This position...?! How? [2]

            //mBarVector.push_back(bar); ERROR! [3]
        }
    }
}
  1. How can I compare the the current iteration on the bar vector, with the reference to a bar from the method parameter? 如何将条形向量上的当前迭代与方法参数对条形的引用进行比较?

  2. Since I'm not using for(int i = 0, ...) how can I erase the position that I'm currently at? 由于我没有使用for(int i = 0,...),如何删除当前所在的位置?

  3. After I remove the bar object from the vector, how can I insert a new one that is coming from a reference (to a shared_ptr)? 从向量中删除bar对象后,如何插入来自引用的新对象(到shared_ptr)?

  1. If you want to do a deep comparison, then you're doing it correctly now, but you need to implement operator==(const Bar&, const Bar&) . 如果您想进行深度比较,那么您现在就可以正确地进行比较,但是您需要实现operator==(const Bar&, const Bar&) If you want to do a shallow comparison, then you need to compare the addresses of the objects: if(b.get() == &bar) 如果要进行浅层比较,则需要比较对象的地址: if(b.get() == &bar)

  2. You can't erase the current item in a range based loop, unless you separately keep track of the index or another iterator. 您不能在基于范围的循环中擦除当前项目,除非您分别跟踪索引或另一个迭代器。 A range based loop is simply not useful in this case. 在这种情况下,基于范围的循环根本没有用。

  3. A shared pointer to the object is in variable b . 指向对象的共享指针位于变量b Simply copy that. 只需复制。 Or, better for performance, move it. 或者,为了提高性能,请移动它。

but I don't know if there is an easier way to do this. 但我不知道是否有更简单的方法可以做到这一点。

There is. 有。

First you need to find an iterator to the element to be moved. 首先,您需要找到要移动的元素的迭代器。 Simplest way to do that, depends again on whether you want shallow or deep comparison. 最简单的方法再次取决于您要进行浅层比较还是深层比较。 For deep comparison, you can use std::find . 要进行深层比较,可以使用std::find You still need to have defined operator==(const Bar&, const Bar&) . 您仍然需要定义operator==(const Bar&, const Bar&) For shallow comparison, you can use std::find_if with a comparison functor that compares the addresses. 对于浅表比较,可以将std::find_if与比较函子(用于比较地址)一起使用。

Once you have the iterator, you can move the pointed element to the end using std::rotate if you want the order of other elements to stay the same. 有了迭代器后,如果希望其他元素的顺序保持不变,则可以使用std::rotate将指向的元素移到末尾。 Simply rotate the vector from the found element to the end, so that the next element becomes the first one. 只需将向量从找到的元素旋转到末尾,以便下一个元素成为第一个元素。 Or, if the order is otherwise irrelevant, then you can do std::swap with the last element which is more efficient. 或者,如果顺序不相关,则可以使用效率更高的最后一个元素执行std::swap

Edit: mkaes proposed std::stable_partition in a comment. 编辑:mkaes在注释中建议了std::stable_partition It would also work and doesn't need a separate find call. 它也可以工作,不需要单独的find调用。 You'll need a comparison functor even if you do use deep comparison. 即使您使用深度比较,也需要一个比较函子。 It'll work for multiple matches too, but that also means that it won't end early if one is found. 它也可以用于多个比赛,但这也意味着如果找到一个比赛,它不会尽早结束。 You can use std::partition , if the order of other elements is irrelvant. 如果其他元素的顺序无关紧要,则可以使用std::partition

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

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