跟踪矢量元素地址

时间:2013-10-02 14:01:56

标签: c++ vector

我想知道是否有办法跟踪向量中元素的地址。

我喜欢使用像std::vector<MyObject> vec这样的实体元素的向量,因为:

  • std :: vector为我做所有分配/解除分配的事情
  • 它还确保我的元素存储在连续的内存中
  • 我可以从使用矢量的所有代码(例如<algorithm>
  • 中获益

这正是我想要的。当我想将矢量元素的地址/引用存储在其他对象中时,就会出现问题。实际上,当std :: vector需要重新分配内存时,问题确实会出现。

我试图找到问题的替代方案:

  • 使用指针/智能指针的向量:不,指针将被连续分配而不是元素

  • 使用指针/智能指针的向量,并为MyObject编写我自己的运算符new / new []: Humm,这似乎更好但没有。通过使用向量来分配我的元素,我可以说:“元素的那些特定集合(我在这里不引用std::set)必须连续分配,而不是所有”。事实上,我可能希望有其他一组元素应该连续分配,因为我想要使用它们的方式并使用向量来实现这一点正是我想要的(我认为)。那也意味着我正在做我想要矢量的工作。

  • 为什么不使用boost multi-index? :在某些方面会做我想要的,因为我想在其他容器中存储我的矢量元素的指针/智能指针。但是没有了,因为我真的想将我的矢量元素的reference / pointer / smartpointer存储在其他对象中,而不仅仅是其他容器。

我最喜欢的是一个向量,它可以给我一个指针对象,它总是指向所需元素的地址,我会像这样使用它:

std::vector<MyObject> vec;
// insert some elements
...
// get a pointer object by index or by using an iterator
// does something like that exist?
std::vector<MyObject>::pointer ptr = vec.get_pointer_at(5); 

// do what I want on the vector except removing the element
...

// use my pointer whatever reallocations occurred or not
ptr->doSomething();

这听起来像一个永远不会失效的迭代器,除了我不需要/想要对其执行算术的事实(+ x,-x,++, - )。

那么,有人可以引导我实现我想要的方式或解释我为什么/我错在哪里想要这样做?如果我错过了一个众所周知的解决方案/或者这个问题已经得到解答,请接受我对STL缺乏知识的道歉。

修改

我认为如果我必须编写这样的指针代码,这意味着我想要一些无用的东西或者我在某处错了(除非有人应该为此编写了一个模板)。所以我更倾向于使用经过验证的C ++习惯来摆脱这个问题。

2 个答案:

答案 0 :(得分:2)

虽然std::vector没有给你这样的指针,但你没有理由不能自己制作一个。所需要的只是一个保持对std::vector对象和索引的引用的类,overloads前缀operator *和中缀operator ->(需要四个重载 - {每个运营商都有{1}}和非const

您可以像这样使用此指针:

const

这些重载的实现将获取std::vector<int> vect = {2, 4, 6, 8, 10, 12, 14, 16}; vect_ptr<int> ptr(vect, 5); // <<== You need to implement this *ptr = 123; cout << *ptr << endl; 的{​​{1}}迭代器,并返回调用std::vector的结果。这看起来像是来自外部的指针,但它指向的对象会随着begin()的内容调整大小而改变。

答案 1 :(得分:0)

据我所知,标准库和Boost中没有任何内容可以解决您的问题。解决方案是实现您自己的元素指针:

template<typename T>
class vector_element
{
public:
    vector_element( std::vector<T>& v, std::size_t i )
      : m_container( v ), m_element_index(i)
    { }

    T& operator*() { return m_container[m_element_index]; }
    T* operator->() { return &m_container[m_element_index]; }
private:
    std::vector<T>& m_container;

    std::size_t m_element_index;
};