The proper way to erase a vector element

This is a discussion on The proper way to erase a vector element within the C++ Programming forums, part of the General Programming Boards category; ok, i know i want to erase element number n, however, i do not "know the iterator" for element n. ...

  1. #1
    Registered User
    Join Date
    Sep 2004
    Posts
    719

    The proper way to erase a vector element

    ok, i know i want to erase element number n, however, i do not "know the iterator" for element n.

    Code:
    vector<int *> a;   
    .... //'a' filled with 20 values.
    a.erase(15); //gives syntax error
    //so does a.erase(a[15]);
    ?????
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,893
    What if you use:

    a.erase(a.begin() + 15);
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    Quote Originally Posted by laserlight
    What if you use:

    a.erase(a.begin() + 15);

    that would make too much sense


    how about
    a.erase((vector<int *>::iterator) &a[15])
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  4. #4
    Even death may die... Dante Shamest's Avatar
    Join Date
    Apr 2003
    Location
    Malaysia
    Posts
    970
    Code:
    a.erase( a.begin() + 15 );
    [edit] My post came reaaally late.

    how about
    a.erase((vector<int *>::iterator) &a[15])
    That shouldn't work.
    Last edited by Dante Shamest; 03-27-2005 at 01:01 AM.

  5. #5
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    Quote Originally Posted by Dante Shamest
    Code:
    a.erase( a.begin() + 15 );
    [edit] My post came reaaally late.

    how about
    a.erase((vector<int *>::iterator) &a[15])

    That shouldn't work.
    i don't see why not. it works fine (so it seems). an iterator is nothing but a pointer. so i grab the & of a[n], tell the erase function that it's an iterator, and BAM! - it compiles.

    if i remember correctly 'iterator' is declared as
    Code:
    template<type T, ......>
    class vector
    {
         typedef  T * iterator;
    }

    but this is of course why i ask.
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  6. #6
    Even death may die... Dante Shamest's Avatar
    Join Date
    Apr 2003
    Location
    Malaysia
    Posts
    970
    i don't see why not. it works fine (so it seems). an iterator is nothing but a pointer. so i grab the & of a[n], tell the erase function that it's an iterator, and BAM! - it compiles.
    I apologise. I thought it wouldn't work because I mistakenly assumed you were working with a vector of ints, instead of a vector of int*s.
    Last edited by Dante Shamest; 03-27-2005 at 01:39 AM.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,893
    i don't see why not. it works fine (so it seems). an iterator is nothing but a pointer. so i grab the & of a[n], tell the erase function that it's an iterator, and BAM! - it compiles.
    But it's something of a kluge, in my opinion.

    You're going from location to pointer then cast to iterator where you can just directly simulate pointer arithmetic with the iterator.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    works just the same

    Code:
    #include <iostream>
    #include <stdlib.h>
    #include <vector>
    using namespace std;
    
    int main(int argc, char *argv[])
    {
      vector<int> a;
      int i;
      
      for(i = 0; i < 10; i++)
        a.push_back(i);
      
      for(i = 0; i < 10; i++)
        cout << a[i] << ' ';
      cout << endl;
      
      a.erase((vector<int>::iterator) &a[5]);
      
      for(i = 0; i < 9; i++)
        cout << a[i] << ' ';
      cout << endl;
      system("PAUSE");	
      return 0;
    }
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  9. #9
    Yes, my avatar is stolen anonytmouse's Avatar
    Join Date
    Dec 2002
    Posts
    2,544
    It works, but is it guaranteed to work? Does the standard guarantee that a vector iterator is a pointer or is this an implementation detail? Calling erase on an item in the middle or beginning of a vector is an expensive operation, as all subsequent elements must be moved. If you need to add and remove elements from the beginning or middle of a container, you should consider another container type.

  10. #10
    Registered User
    Join Date
    Sep 2004
    Posts
    719
    Quote Originally Posted by anonytmouse
    It works, but is it guaranteed to work? Does the standard guarantee that a vector iterator is a pointer or is this an implementation detail? Calling erase on an item in the middle or beginning of a vector is an expensive operation, as all subsequent elements must be moved. If you need to add and remove elements from the beginning or middle of a container, you should consider another container type.

    i'm not arguing that my ingenius, super hackish way of erasing an element is the correct way. hell, look at the thread title. i am saying that it DOES work. i would not go into a job interview and do it that way, that's for sure.

    a vector is fine. i only need to erase a pointer here and there. it won't happen more than, on average, about 0.5 times per program execution and it only will contain about 6 (pointer) elements tops. i'm not to concerned with it's efficiency.
    i seem to have GCC 3.3.4
    But how do i start it?
    I dont have a menu for it or anything.

  11. #11
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    Vector supplies random access iterators, therefore begin() + n is defined, and constant time. if begin() is a pointer then it is identical to misplaced hack. In the new draft standard, and all the implementations I know about
    Code:
    static_cast<std::vector<ValueT>::value_type *>(&v[0])
    is a pointer to v.size() contiguously allocated ValueT's However, even though pointers and iterators do exactly the same things there is no requrement for there to be a well defined conversion from pointer to iterator. ValueT *p = &(*it); where it is a valid iterator should be kosher, but going the other way is not. Consider, for example, debug iterators that invalidate themselves whenever capacity() is called with a large value.

    As a side node std::swap(v[n],v.back()); v.pop_back(); will get rid of element n, in constant (very fast) time, but does not preserve order. Naturally v[n] = v.back(); v.pop_back(); works as well and is faster for types that may not have specialised std::swap.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Question about erase()
    By Sharke in forum C++ Programming
    Replies: 8
    Last Post: 06-10-2009, 01:22 AM
  2. Proper nouns
    By Ducky in forum C++ Programming
    Replies: 12
    Last Post: 12-31-2007, 10:11 AM
  3. Question about using erase() with lists (STL)
    By apacz in forum C++ Programming
    Replies: 2
    Last Post: 11-01-2005, 10:51 AM
  4. string erase function problems
    By westm2000 in forum C++ Programming
    Replies: 5
    Last Post: 09-15-2003, 10:19 PM
  5. erase in vector
    By stimpyzu in forum C++ Programming
    Replies: 18
    Last Post: 11-23-2002, 12:23 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21