Supplying an iterator when inserting into vector??

Discussion in 'C++' started by desktop, Jun 4, 2007.

  1. desktop

    desktop Guest

    Why does insert only work when specifying an iterator plus the object to
    be inserted:

    std::vector<int> t;
    std::vector<int>::iterator it;
    it = t.begin();

    t.insert(it,33);

    If I use push_back instead I don't need to supply the iterator. But what
    are the reason the insert only works with an iterator?
     
    desktop, Jun 4, 2007
    #1
    1. Advertising

  2. desktop wrote:
    > Why does insert only work when specifying an iterator plus the object
    > to be inserted:
    >
    > std::vector<int> t;
    > std::vector<int>::iterator it;
    > it = t.begin();
    >
    > t.insert(it,33);
    >
    > If I use push_back instead I don't need to supply the iterator. But
    > what are the reason the insert only works with an iterator?


    Uh... 'push_back(value)' does 'insert(end(), value)'. How would you
    insert into any place except the end if you don't give an iterator?

    And if you wanted an overloaded 'insert' without an interator, what
    would the difference be between it and 'push_back'? Do you expect it
    to only do "insert into beginning"?

    Do you not understand that 'insert' is a generic function to place
    the value _anywhere_ in the vector?

    V
    --
    Please remove capital 'A's when replying by e-mail
    I do not respond to top-posted replies, please don't ask
     
    Victor Bazarov, Jun 4, 2007
    #2
    1. Advertising

  3. On Jun 4, 8:29 am, desktop <> wrote:
    > Why does insert only work when specifying an iterator plus the object to
    > be inserted:
    >
    > std::vector<int> t;
    > std::vector<int>::iterator it;
    > it = t.begin();
    >
    > t.insert(it,33);
    >
    > If I use push_back instead I don't need to supply the iterator. But what
    > are the reason the insert only works with an iterator?


    push_back by default inserts at the end of the container while insert
    allows you to mention a position where you can insert.
     
    Naresh Rautela, Jun 4, 2007
    #3
  4. desktop

    desktop Guest

    Naresh Rautela wrote:
    > On Jun 4, 8:29 am, desktop <> wrote:
    >> Why does insert only work when specifying an iterator plus the object to
    >> be inserted:
    >>
    >> std::vector<int> t;
    >> std::vector<int>::iterator it;
    >> it = t.begin();
    >>
    >> t.insert(it,33);
    >>
    >> If I use push_back instead I don't need to supply the iterator. But what
    >> are the reason the insert only works with an iterator?

    >
    > push_back by default inserts at the end of the container while insert
    > allows you to mention a position where you can insert.
    >


    Ok thanks for the info. When I want to extract an element from the
    vector I would use something like:

    t.at(0);

    But if I have a vector containing my own object that I have defined in a
    class 'test' (with a getInt() function returning a private integer) I
    would like to use iterators for this:

    std::vector<test*> t2;
    std::vector<test*>::iterator it2;
    it2 = t2.begin();


    test* tt2 = new test(707);
    t2.insert(it2,tt2);
    *it2->getInt()

    But this does not work. Are iterators only used for inserting and not
    extracting custom objects?
     
    desktop, Jun 4, 2007
    #4
  5. On Jun 4, 8:50 am, desktop <> wrote:
    > Naresh Rautela wrote:
    > > On Jun 4, 8:29 am, desktop <> wrote:
    > >> Why does insert only work when specifying an iterator plus the object to
    > >> be inserted:

    >
    > >> std::vector<int> t;
    > >> std::vector<int>::iterator it;
    > >> it = t.begin();

    >
    > >> t.insert(it,33);

    >
    > >> If I use push_back instead I don't need to supply the iterator. But what
    > >> are the reason the insert only works with an iterator?

    >
    > > push_back by default inserts at the end of the container while insert
    > > allows you to mention a position where you can insert.

    >
    > Ok thanks for the info. When I want to extract an element from the
    > vector I would use something like:
    >
    > t.at(0);
    >
    > But if I have a vector containing my own object that I have defined in a
    > class 'test' (with a getInt() function returning a private integer) I
    > would like to use iterators for this:
    >
    > std::vector<test*> t2;
    > std::vector<test*>::iterator it2;
    > it2 = t2.begin();
    >
    > test* tt2 = new test(707);
    > t2.insert(it2,tt2);
    > *it2->getInt()
    >
    > But this does not work. Are iterators only used for inserting and not
    > extracting custom objects?- Hide quoted text -
    >
    > - Show quoted text -


    You are storing the start of the vector(it2) and then inserting at the
    start of the vector. Then it2 is no longer the start but start + 1.
    Since there is no element at start+1, you may be getting a
    segmentation violation.
     
    Naresh Rautela, Jun 4, 2007
    #5
  6. On Jun 4, 8:50 am, desktop <> wrote:
    > Naresh Rautela wrote:
    > > On Jun 4, 8:29 am, desktop <> wrote:
    > >> Why does insert only work when specifying an iterator plus the object to
    > >> be inserted:

    >
    > >> std::vector<int> t;
    > >> std::vector<int>::iterator it;
    > >> it = t.begin();

    >
    > >> t.insert(it,33);

    >
    > >> If I use push_back instead I don't need to supply the iterator. But what
    > >> are the reason the insert only works with an iterator?

    >
    > > push_back by default inserts at the end of the container while insert
    > > allows you to mention a position where you can insert.

    >
    > Ok thanks for the info. When I want to extract an element from the
    > vector I would use something like:
    >
    > t.at(0);
    >
    > But if I have a vector containing my own object that I have defined in a
    > class 'test' (with a getInt() function returning a private integer) I
    > would like to use iterators for this:
    >
    > std::vector<test*> t2;
    > std::vector<test*>::iterator it2;
    > it2 = t2.begin();
    >
    > test* tt2 = new test(707);
    > t2.insert(it2,tt2);
    > *it2->getInt()
    >
    > But this does not work. Are iterators only used for inserting and not
    > extracting custom objects?- Hide quoted text -
    >
    > - Show quoted text -


    try this

    void main()
    {
    std::vector<test*> t2;
    std::vector<test*>::iterator it2;
    //it2 = t2.begin();

    test* tt2 = new test(707);
    t2.insert(it2,tt2);
    it2 = t2.begin();
    std::cout << (*it2)->getInt();
    }
     
    Naresh Rautela, Jun 4, 2007
    #6
  7. desktop

    Andre Kostur Guest

    desktop <> wrote in news:f41cc2$oai$-c.dk:

    > Naresh Rautela wrote:
    >> On Jun 4, 8:29 am, desktop <> wrote:
    >>> Why does insert only work when specifying an iterator plus the
    >>> object to be inserted:
    >>>
    >>> std::vector<int> t;
    >>> std::vector<int>::iterator it;
    >>> it = t.begin();
    >>>
    >>> t.insert(it,33);
    >>>
    >>> If I use push_back instead I don't need to supply the iterator. But
    >>> what are the reason the insert only works with an iterator?

    >>
    >> push_back by default inserts at the end of the container while insert
    >> allows you to mention a position where you can insert.
    >>

    >
    > Ok thanks for the info. When I want to extract an element from the
    > vector I would use something like:
    >
    > t.at(0);


    If you want bounds-checking... if not, then you can also use:

    t[0]

    Of course, assuming that there is a 0-th object in the vector.

    > But if I have a vector containing my own object that I have defined in
    > a class 'test' (with a getInt() function returning a private integer)
    > I would like to use iterators for this:
    >
    > std::vector<test*> t2;
    > std::vector<test*>::iterator it2;
    > it2 = t2.begin();


    it2 == t2.begin(). And since the vector is empty, it2 == t2.end() as
    well.

    > test* tt2 = new test(707);
    > t2.insert(it2,tt2);


    With this insertion, you may or may not have invalidated any and all
    iterators into the container.

    > *it2->getInt()


    This may or may not be dereferencing an invalid iterator. If it is, then
    it is Undefined Behaviour. Anything can happen. And, IIRC, the
    precedence rules say you'd have to write that as:

    (*it2)->getInt()

    -> (member selection) has a higher precedence than * (dereferencing).

    > But this does not work. Are iterators only used for inserting and not
    > extracting custom objects?


    They're used for both. But you need to understand when iterators become
    invalid. For vectors, any and all iterators into the vector may become
    invalid upon insertion if the insertion causes a reallocation of the
    vector.
     
    Andre Kostur, Jun 4, 2007
    #7
  8. Naresh Rautela wrote:
    >> std::vector<test*> t2;
    >> std::vector<test*>::iterator it2;
    >> it2 = t2.begin();
    >>
    >> test* tt2 = new test(707);
    >> t2.insert(it2,tt2);
    >> *it2->getInt()


    > You are storing the start of the vector(it2) and then inserting at the
    > start of the vector. Then it2 is no longer the start but start + 1.


    Nonsense. The right answer is that it2 gets invalidated when items
    are inserted in the vector.
    Even if it didn't get invalidated (eg. because of a reserve()) it
    would still point to the first element of the vector. Inserting
    elements in the vector doesn't change any existing iterator.

    Your answer may be correct for eg. a std::list where iterators
    are not invalidated after insertion.
     
    Juha Nieminen, Jun 4, 2007
    #8
  9. desktop

    Guest

    On Jun 4, 9:15 am, Naresh Rautela <> wrote:
    > On Jun 4, 8:50 am, desktop <> wrote:
    >
    > > std::vector<test*> t2;
    > > std::vector<test*>::iterator it2;
    > > it2 = t2.begin();

    >
    > > test* tt2 = new test(707);
    > > t2.insert(it2,tt2);
    > > *it2->getInt()

    >
    > > But this does not work. Are iterators only used for inserting and not
    > > extracting custom objects?- Hide quoted text -

    >
    > You are storing the start of the vector(it2) and then inserting at the
    > start of the vector. Then it2 is no longer the start but start + 1.


    Actually, after the insertion the iterator it2 is no longer valid.
    Inserting into a vector invalidates any pre-existing iterators into
    that vector. Try changing the second-to-last line to:

    it2 = t2.insert(it2,tt2);

    Also, consider using a vector<test> instead of a vector<test*>. As the
    code is written now, you (not the vector) are responsible for deleting
    all the test objects you instantiate using new. Also, your code will
    leak a test instance if vector::insert throws an exception.
     
    , Jun 4, 2007
    #9
  10. desktop

    red floyd Guest

    Naresh Rautela wrote:

    >
    > void main()


    Illformed code. main *ALWAYS* returns int.

    int main()
    > {
    > std::vector<test*> t2;
    > std::vector<test*>::iterator it2;
    > //it2 = t2.begin();
    >
    > test* tt2 = new test(707);
    > t2.insert(it2,tt2);
    > it2 = t2.begin();
    > std::cout << (*it2)->getInt();
    > }
    >
     
    red floyd, Jun 4, 2007
    #10
  11. On Jun 4, 9:56 am, red floyd <> wrote:
    > Naresh Rautela wrote:
    >
    > > void main()

    >
    > Illformed code. main *ALWAYS* returns int.
    >
    > int main()
    >
    >
    >
    > > {
    > > std::vector<test*> t2;
    > > std::vector<test*>::iterator it2;
    > > //it2 = t2.begin();

    >
    > > test* tt2 = new test(707);
    > > t2.insert(it2,tt2);
    > > it2 = t2.begin();
    > > std::cout << (*it2)->getInt();
    > > }- Hide quoted text -

    >
    > - Show quoted text -


    Thanks for pointing these out and help me learn.
     
    Naresh Rautela, Jun 4, 2007
    #11
  12. desktop

    desktop Guest

    Andre Kostur wrote:
    > desktop <> wrote in news:f41cc2$oai$-c.dk:
    >
    >> Naresh Rautela wrote:
    >>> On Jun 4, 8:29 am, desktop <> wrote:
    >>>> Why does insert only work when specifying an iterator plus the
    >>>> object to be inserted:
    >>>>
    >>>> std::vector<int> t;
    >>>> std::vector<int>::iterator it;
    >>>> it = t.begin();
    >>>>
    >>>> t.insert(it,33);
    >>>>
    >>>> If I use push_back instead I don't need to supply the iterator. But
    >>>> what are the reason the insert only works with an iterator?
    >>> push_back by default inserts at the end of the container while insert
    >>> allows you to mention a position where you can insert.
    >>>

    >> Ok thanks for the info. When I want to extract an element from the
    >> vector I would use something like:
    >>
    >> t.at(0);

    >
    > If you want bounds-checking... if not, then you can also use:
    >
    > t[0]
    >
    > Of course, assuming that there is a 0-th object in the vector.
    >
    >> But if I have a vector containing my own object that I have defined in
    >> a class 'test' (with a getInt() function returning a private integer)
    >> I would like to use iterators for this:
    >>
    >> std::vector<test*> t2;
    >> std::vector<test*>::iterator it2;
    >> it2 = t2.begin();

    >
    > it2 == t2.begin(). And since the vector is empty, it2 == t2.end() as
    > well.
    >
    >> test* tt2 = new test(707);
    >> t2.insert(it2,tt2);

    >
    > With this insertion, you may or may not have invalidated any and all
    > iterators into the container.
    >
    >> *it2->getInt()

    >
    > This may or may not be dereferencing an invalid iterator. If it is, then
    > it is Undefined Behaviour. Anything can happen.


    To avoid this I could just update the iterator after insertion with :
    it2 = t2.begin() As long as I make sure to update the iterator
    afterwards I am sure that it is still valid right?
     
    desktop, Jun 4, 2007
    #12
  13. desktop

    BobR Guest

    desktop wrote in message ...
    > Andre Kostur wrote:
    > > desktop wrote in ....
    > >> But if I have a vector containing my own object that I have defined in
    > >> a class 'test' (with a getInt() function returning a private integer)
    > >> I would like to use iterators for this:
    > >>
    > >> std::vector<test*> t2;
    > >> std::vector<test*>::iterator it2;
    > >> it2 = t2.begin();

    > >
    > > it2 == t2.begin(). And since the vector is empty, it2 == t2.end() as
    > > well.
    > >
    > >> test* tt2 = new test(707);
    > >> t2.insert(it2,tt2);

    > >
    > > With this insertion, you may or may not have invalidated any and all
    > > iterators into the container.
    > >
    > >> *it2->getInt()

    > >
    > > This may or may not be dereferencing an invalid iterator. If it is,

    then
    > > it is Undefined Behaviour. Anything can happen.

    >
    > To avoid this I could just update the iterator after insertion with :
    > it2 = t2.begin() As long as I make sure to update the iterator
    > afterwards I am sure that it is still valid right?


    Just for kicks, try:

    // .... fill the vector with something
    it2 = t2.begin(); // update the iterator
    // *it2->getInt(); // ?? *( it2->getInt() ) ??
    int num = (*it2)->getInt();

    --
    Bob R
    POVrookie
     
    BobR, Jun 5, 2007
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?U3llZCBHaGF5YXM=?=

    Problem writing cookie when supplying Path property

    =?Utf-8?B?U3llZCBHaGF5YXM=?=, May 6, 2005, in forum: ASP .Net
    Replies:
    2
    Views:
    447
    =?Utf-8?B?bWljcm9zb2Z0LnB1YmxpYy5kb3RuZXQuZnJhbWV3
    May 6, 2005
  2. sp
    Replies:
    3
    Views:
    709
    Philippe Poulard
    Jan 27, 2006
  3. Replies:
    8
    Views:
    1,939
    Csaba
    Feb 18, 2006
  4. Henrik Goldman
    Replies:
    1
    Views:
    381
    =?UTF-8?B?RXJpayBXaWtzdHLDtm0=?=
    Oct 21, 2007
  5. zl2k
    Replies:
    27
    Views:
    1,596
    Francesco S. Carta
    Sep 7, 2010
Loading...

Share This Page