在std :: vector中获取元素位置

时间:2013-02-18 21:44:07

标签: c++ stdvector

如何在向量中获取元素的位置,其中元素是类。有没有办法做到这一点?

示例代码:

class Object
{
  public:
    void Destroy()
    {
      // run some code to get remove self from vector
    }
}

在main.cpp中:

std::vector<Object> objects;
objects.push_back( <some instances of Object> );
// Some more code pushing back some more stuff

int n = 20;
objects.at(n).Destroy(); // Assuming I pushed back 20 items or more

所以我想我希望能够编写一个方法或类的成员,它将在向量中返回它自己的位置......这可能吗?

编辑:

由于困惑,我应该更好地解释。

void Destroy(std::vector<Object>& container){
  container.erase( ?...? );
}

问题是,我怎样才能找到要擦除的号码......?显然这是不可能的......我认为可能不是......

4 个答案:

答案 0 :(得分:1)

您可以使用std::find查找vector中的元素(假设您为==实施了一个比较运算符(Object)。但是,有两大问题:

  1. 如果您需要在容器中查找元素,那么使用std::mapstd::set等有序容器可以获得更好的性能(查找O(log(N)) vs {{1}中的操作}}
  2. O(N)不应该是从容器中移除自己的人。 Object不应该知道或关注它在哪里,因为它打破了封装。相反,容器的所有者应该关注自己的这些任务。

答案 1 :(得分:1)

对象可以这样擦除自己:

void Destroy(std::vector<Object>& container);
{
  container.erase(container.begin() + (this - &container[0]));
}

这会像你期望的那样工作,但它让我觉得非常糟糕的设计。会员不应该了解他们的容器。它们应该存在(从他们自己的角度来看)无法辨认的不确定性。创造和破坏应留给他们的创造者。

答案 2 :(得分:0)

向量中的对象不会自动知道它们在向量中的位置。

您可以为每个对象提供该信息,但更容易:从向量中移除对象。然后它的析构函数会自动运行。

然后,对象也可以在其他容器中使用。


示例:

#include <algorithm>
#include <iostream>
#include <vector>

class object_t
{
private:
    int     id_;
public:
    int id() const { return id_; }

    ~object_t() {}
    explicit object_t( int const id ): id_( id ) {}
};

int main()
{
    using namespace std;
    vector<object_t> objects;

    for( int i = 0;  i <= 33;  ++i )
    {
        objects.emplace_back( i );
    }

    int const n = 20;
    objects.erase( objects.begin() + n );

    for( auto const& o : objects )
    {
        cout << o.id() << ' ';
    }
    cout << endl;
}

答案 3 :(得分:0)

如果你需要销毁向量中的第n个项目,那么最简单的方法是使用std::begin()从头开始获取迭代器并调用std::advance()来推进你想要的多少个地方,所以像:

std::vector<Object> objects;
const size_t n = 20;

auto erase_iter = std::advance(std::begin(objects), n);

objects.erase(erase_iter);

如果要在向量中找到项的索引,请使用std::find获取迭代器并从头开始调用std::distance

类似于:

Object object_to_find;
std::vector<Object> objects;

auto object_iter = std::find(std::begin(objects), std::end(objects), object_to_find);

const size_t n = std::distance(std::begin(objects), object_iter);

这确实意味着您需要为对象实现相等运算符。或者你可以尝试类似的东西:

auto object_iter = std::find(std::begin(objects), std::end(objects), 
  [&object_to_find](const Object& object) -> bool { return &object_to_find == &object; });

虽然为了实现这一点,object_to_find需要是实际列表中的一个,因为它只是比较地址。