Convert iterator to pointer?

前端 未结 12 2274
野性不改
野性不改 2020-12-14 14:20

I have a std::vector with n elements. Now I need to pass a pointer to a vector that has the last n-1 elements to a function.

F

相关标签:
12条回答
  • 2020-12-14 14:43

    A vector is a container with full ownership of it's elements. One vector cannot hold a partial view of another, even a const-view. That's the root cause here.

    If you need that, make your own container that has views with weak_ptr's to the data, or look at ranges. Pair of iterators (even pointers work well as iterators into a vector) or, even better, boost::iterator_range that work pretty seamlessly.

    It depends on the templatability of your code. Use std::pair if you need to hide the code in a cpp.

    0 讨论(0)
  • 2020-12-14 14:46

    The direct answer to your question is yes. If foo is a vector, you can do this: &foo[1].

    This only works for vectors however, because the standard says that vectors implement storage by using contigious memory.

    But you still can (and probably should) pass iterators instead of raw pointers because it is more expressive. Passing iterators does not make a copy of the vector.

    0 讨论(0)
  • 2020-12-14 14:48

    If you can, a better choice may be to change the function to take either an iterator to an element or a brand new vector (if it does not modify).

    While you can do this sort of things with arrays since you know how they are stored, it's probably a bad idea to do the same with vectors. &foo[1] does not have the type vector<int>*.

    Also, while the STL implementation is available online, it's usually risky to try and rely on the internal structure of an abstraction.

    0 讨论(0)
  • 2020-12-14 14:48

    For example, my vector<int> foo contains (5,2,6,87,251). A function takes vector<int>* and I want to pass it a pointer to (2,6,87,251).

    A pointer to a vector<int> is not at all the same thing as a pointer to the elements of the vector.

    In order to do this you will need to create a new vector<int> with just the elements you want in it to pass a pointer to. Something like:

     vector<int> tempVector( foo.begin()+1, foo.end());
    
     // now you can pass &tempVector to your function
    

    However, if your function takes a pointer to an array of int, then you can pass &foo[1].

    0 讨论(0)
  • 2020-12-14 14:49

    Your function shouldn't take vector<int>*; it should take vector<int>::iterator or vector<int>::const_iterator as appropriate. Then, just pass in foo.begin() + 1.

    0 讨论(0)
  • 2020-12-14 14:51

    I haven't tested this but could you use a set of pairs of iterators instead? Each iterator pair would represent the begin and end iterator of the sequence vector. E.g.:

    typedef std::vector<int> Seq;
    typedef std::pair<Seq::const_iterator, Seq::const_iterator> SeqRange;
    
    bool operator< (const SeqRange& lhs, const SeqRange& rhs)
    {
        Seq::const_iterator lhsNext = lhs.first;
        Seq::const_iterator rhsNext = rhs.first;
    
        while (lhsNext != lhs.second && rhsNext != rhs.second)
            if (*lhsNext < *rhsNext)
                return true;
            else if (*lhsNext > *rhsNext)
                return false;
    
        return false;
    }
    
    typedef std::set<SeqRange, std::less<SeqRange> > SeqSet;
    
    Seq sequences;
    
    void test (const SeqSet& seqSet, const SeqRange& seq)
    {
        bool find = seqSet.find (seq) != seqSet.end ();
        bool find2 = seqSet.find (SeqRange (seq.first + 1, seq.second)) != seqSet.end ();
    }
    

    Obviously the vectors have to be held elsewhere as before. Also if a sequence vector is modified then its entry in the set would have to be removed and re-added as the iterators may have changed.

    Jon

    0 讨论(0)
提交回复
热议问题