set erase of null and nonexistent elements

Discussion in 'C++' started by puzzlecracker, Sep 14, 2008.

  1. I have a std::set<A *> and assume that operator () is implemented to
    establish relative order and for equality

    What does standard or popular implementation dictate of the following
    example:

    #include<set>
    #include "A.h"

    using std::set


    int main(int argc, char **argv)
    {
    std::set<A *> aSet;
    A *nullA=0;
    A *a=new A("NOT HERE")

    set.insert(new A("something"))
    //here is the list of operations I am
    aSet.erase(nullA);
    aSet.erase(a);

    //clean up and return
    return 0;
    }

    How do standard containers (instantiated with some pointer to user-
    defined type) behave in the presence of null pointer?

    Thanks
     
    puzzlecracker, Sep 14, 2008
    #1
    1. Advertising

  2. puzzlecracker

    Kai-Uwe Bux Guest

    puzzlecracker wrote:

    > I have a std::set<A *> and assume that operator () is implemented to
    > establish relative order and for equality


    Huh?

    Anyway, the code below does not make any use of operator(). It uses
    std::less<A*>. If that is not specialized in A.h, the remarks below apply.
    If it is specialzed, you have to make sure it is a strict total ordering.


    > What does standard or popular implementation dictate of the following
    > example:
    >
    > #include<set>
    > #include "A.h"
    >
    > using std::set
    >
    >
    > int main(int argc, char **argv)
    > {
    > std::set<A *> aSet;
    > A *nullA=0;
    > A *a=new A("NOT HERE")
    >
    > set.insert(new A("something"))
    > //here is the list of operations I am
    > aSet.erase(nullA);


    null-op: nullA is not in the set.

    > aSet.erase(a);


    null-op: a is not in the set.

    >
    > //clean up and return
    > return 0;
    > }
    >
    > How do standard containers (instantiated with some pointer to user-
    > defined type) behave in the presence of null pointer?


    If the null-pointer is an element of the set, it will be removed. Otherwise,
    trying to remove it, is a null-op. This holds, unless std::set<> is used
    with a custom predicate or a specialized version of std::less<>.


    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Sep 14, 2008
    #2
    1. Advertising


  3. > Anyway, the code below does not make any use of operator(). It uses
    > std::less<A*>. If that is not specialized in A.h, the remarks below apply.
    > If it is specialzed, you have to make sure it is a strict total ordering.


    I meant something else entirely. I was refering to algorithms, such as
    find_if where passed predicate, which implemented operator () for
    comparison. I assume set uses operator == to locate elements of UDT.
    Correct me if am wrong.



    > > What does standard or popular implementation dictate of the following
    > > example:

    >
    > > #include<set>
    > > #include "A.h"

    >
    > > using std::set

    >
    > > int main(int argc, char **argv)
    > > {
    > > std::set<A *> aSet;
    > > A *nullA=0;
    > > A *a=new A("NOT HERE")

    >
    > > set.insert(new A("something"))
    > > //here is the list of operations I am
    > > aSet.erase(nullA);

    >
    > null-op: nullA is not in the set.
    >
    > > aSet.erase(a);

    >
    > null-op: a is not in the set.
    >
    >
    >
    > > //clean up and return
    > > return 0;
    > > }

    >
    > > How do standard containers (instantiated with some pointer to user-
    > > defined type) behave in the presence of null pointer?


    Well, if we insert a null pointer into a set, wouldn't it cause an
    error whenever the container would try to invoke its member.

    Wait, perhaps an std container doesn't do that, hence no errors are to
    be seen, then how does find work?
     
    puzzlecracker, Sep 15, 2008
    #3
  4. puzzlecracker

    Kai-Uwe Bux Guest

    puzzlecracker wrote:

    >
    >> Anyway, the code below does not make any use of operator(). It uses
    >> std::less<A*>. If that is not specialized in A.h, the remarks below
    >> apply. If it is specialzed, you have to make sure it is a strict total
    >> ordering.

    >
    > I meant something else entirely. I was refering to algorithms, such as
    > find_if where passed predicate, which implemented operator () for
    > comparison. I assume set uses operator == to locate elements of UDT.
    > Correct me if am wrong.


    You are wrong: std::set<> uses std::less<> to decide whether two elements
    are equal. The idea is that a == b can be characterized as neither a < b
    nor b < a. In fact, operator== is not used by std::set<> at all.


    >> > What does standard or popular implementation dictate of the following
    >> > example:

    >>
    >> > #include<set>
    >> > #include "A.h"

    >>
    >> > using std::set

    >>
    >> > int main(int argc, char **argv)
    >> > {
    >> > std::set<A *> aSet;
    >> > A *nullA=0;
    >> > A *a=new A("NOT HERE")

    >>
    >> > set.insert(new A("something"))
    >> > //here is the list of operations I am
    >> > aSet.erase(nullA);

    >>
    >> null-op: nullA is not in the set.
    >>
    >> > aSet.erase(a);

    >>
    >> null-op: a is not in the set.
    >>
    >>
    >>
    >> > //clean up and return
    >> > return 0;
    >> > }

    >>
    >> > How do standard containers (instantiated with some pointer to user-
    >> > defined type) behave in the presence of null pointer?

    >
    > Well, if we insert a null pointer into a set, wouldn't it cause an
    > error whenever the container would try to invoke its member.


    Yes. Dereferencing a null-pointer is undefined behavior. That, however, does
    not imply that you cannot insert the null-pointer into a set. You just have
    to make sure that it does not get dereferenced.


    > Wait, perhaps an std container doesn't do that, hence no errors are to
    > be seen, then how does find work?


    Post code, so that we can discuss find() or find_if() meaningfully. I don't
    trust my crystal ball and can only guess what you are looking at.



    Best

    Kai-Uwe Bux
     
    Kai-Uwe Bux, Sep 15, 2008
    #4
  5. puzzlecracker

    James Kanze Guest

    On Sep 15, 1:21 am, Kai-Uwe Bux <> wrote:
    > puzzlecracker wrote:


    [...]
    > > Well, if we insert a null pointer into a set, wouldn't it
    > > cause an error whenever the container would try to invoke
    > > its member.


    > Yes. Dereferencing a null-pointer is undefined behavior. That,
    > however, does not imply that you cannot insert the
    > null-pointer into a set. You just have to make sure that it
    > does not get dereferenced.


    Also, std::set<T*> never dereferences the pointers it contains.
    Let's face it, this is pure template code, with no partial
    specializations or whatever, so the code is exactly the same for
    pointers and for non-pointers.

    Of course, if you explicitly specialize std::less< A* > so that
    it does dereference the pointer, you'll get into deep trouble if
    the pointer is null. But that would be just stupid (unless your
    goal is obfuscation). The standard defines a full ordering on
    pointers (using std::less, but not with <), and requires
    std::set to use this ordering by default. A reader who sees a
    set instantiated without a custom ordering function has a right
    to expect that this ordering is what is used, and not something
    else. (If this ordering isn't appropriate, and it often isn't,
    then you should says so explicitly, by providing an ordering
    argument to the template instantiation.)

    --
    James Kanze (GABI Software) email:
    Conseils en informatique orientée objet/
    Beratung in objektorientierter Datenverarbeitung
    9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
     
    James Kanze, Sep 15, 2008
    #5
    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. Replies:
    1
    Views:
    384
    Peter Hansen
    Jul 6, 2004
  2. erase vs. erase

    , Mar 25, 2006, in forum: C++
    Replies:
    7
    Views:
    369
    Pete Becker
    Mar 30, 2006
  3. Hal Fulton

    fxruby (nonexistent) html widget

    Hal Fulton, Aug 11, 2005, in forum: Ruby
    Replies:
    3
    Views:
    100
    Lothar Scholz
    Aug 11, 2005
  4. Daniel Berger
    Replies:
    5
    Views:
    693
    Nobuyoshi Nakada
    Feb 21, 2008
  5. Jeff
    Replies:
    3
    Views:
    205
    Ben Morrow
    Feb 10, 2004
Loading...

Share This Page