In C ++, how can I get a pointer to a vector?

I write C ++ code that controls a bunch of vectors that change in size and therefore are constantly redistributed.

I would like to get a "pointer" to these vectors, which remains valid even after the redistribution of the vector. In particular, I just want these “pointers” to remember which vector they are pointing to, and the index they are pointing to. When I cast them using the standard (* ptr) syntax, I just want them to do an obvious search.

Obviously, the actual pointers will not be valid after the redistribution, and I understand that iterators are not valid after the redistribution. Also note that I don't care if elements are inserted in front of my objects, so these “pointers” really don't need to remember anything except the vector and index.

Now I could easily write such a class myself. Has anyone (Boost? STL?) Done this for me already?

Change . The answers do not affect my question. I asked if this functionality is any standard library. Do I accept the answer as no?

+3
source share
7 answers

std:: pair < vector *, int > , , .
, :

template<class T> class VectorElementPointer
{
  vector<T>& vectorref;
  typename vector<T>::size_type index;
public:
  VectorElementPointer(vector<T>& vref, typename vector<T>::size_type index):vectorref(vref),index(index){}
  T& operator*() const {return vectorref[index];}
  T* operator->() const {return &vectorref[index];}
};

, , STL, Boost , .

+22

, .

+9

. , , .

void print(const std::string& i)
{
    std::cout << "<" << i << "> ";
}
int main()
{
    typedef std::vector<std::string> Vector;

    Vector v;
    v.push_back("H");
    v.push_back("E");
    v.push_back("W");
    StrongIterator<Vector> it0(v, 0);
    StrongIterator<Vector> it3(v, v.end());

    std::for_each(it0.it(), it3.it(), print);
    std::cout << std::endl;

    v.push_back("O");
    std::for_each(it0.it(), it3.it(), print);

    std::cout << *it0;
    std::cout << it0->c_str();

    return 0;
}

.

template <typename TVector>
class StrongIterator
{
public:
    typedef typename TVector::iterator iterator;
    typedef typename TVector::size_type size_type;
    typedef typename TVector::value_type value_type;
    StrongIterator(TVector& vector,
                   size_type index):
        vector_(vector),
        index_(index)
    {}
    StrongIterator(TVector& vector,
                   iterator it):
        vector_(vector),
        index_(std::distance(vector.begin(), it))
    {}
    iterator it()
    {
        iterator it = vector_.begin();
        std::advance(it, index_);
        return it;
    }
    value_type& operator*()
    {
        return vector_[index_];
    }
    value_type* operator->()
    {
        return &vector_[index_];
    }
private:
    TVector& vector_;
    size_type index_;
};
+3

boost:: iterator_facade:

// Warning: Untested, not even compiled
template<class VectorT>
class VectorIndex : 
    public boost::iterator_facade<VectorIndex, typename VectorT::reference, boost::random_access_traversal_tag>
{
public:
    VectorIndex(VectorT& Vec, typename VectorT::size_type Index)
    : m_Vec(Vec), m_Index(Index)
    {
    }

private:
    friend class boost::iterator_core_access;

    void increment()
    {
        ++m_Index;
    }

    void decrement()
    {
        --m_Index;
    } 

    void advance(difference_type N)
    {
        m_Index += N;
    }

    difference_type distance_to(const VectorIndex& Other)
    {
        assert(&this->m_Vec == &Other.m_Vec);
        return Other.m_Index = this->m_Index; 
    }

    bool equal(const VectorIndex& Other)const
    {
        return (this->m_Vec == Other.m_Vec)
            && (this->m_Index == Other.m_Index);
    }

    VectorT::reference dereference() const 
    {
        return m_Vec[m_Index];
    }

    VectorT m_Vec;
    VectorT::size_type m_Index;
};
+2

, , , "" , . STL, , , , - < > . , std:: list < > , ; , .

std:: list: http://www.cplusplus.com/reference/stl/list/

+1

, , . , - .

, - , , .

0

Depending on your usage pattern, std :: deque may suit your requirements. Pointers in deque are only invalid if you do not insert or remove elements at the beginning or end of the word push_front () and push_back () do not invalidate pointers in deque, but make other changes. You get basically the same interface as the vector, but of course the main repository is not contiguous.

0
source

Source: https://habr.com/ru/post/1706415/


All Articles