Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > set erase of null and nonexistent elements

Reply
Thread Tools

set erase of null and nonexistent elements

 
 
puzzlecracker
Guest
Posts: n/a
 
      09-14-2008
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
 
Reply With Quote
 
 
 
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      09-14-2008
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
 
Reply With Quote
 
 
 
 
puzzlecracker
Guest
Posts: n/a
 
      09-14-2008

> 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?
 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      09-14-2008
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
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      09-15-2008
On Sep 15, 1:21 am, Kai-Uwe Bux <(E-Mail Removed)> 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:(E-Mail Removed)
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
erase vs. erase al.cpwn@gmail.com C++ 7 03-30-2006 11:45 AM
How do i erase all information in my orkut and erase the link to the orkut account? mountbatten@gmail.com Computer Support 1 10-31-2005 12:03 AM
Compiling nonexistent cvsignore file python-listNOSPAMthankyou@lahf.org Python 1 07-06-2004 11:31 AM
Comcast Customer Service - NonExistent UnderDog Computer Support 6 11-11-2003 07:04 PM
How do I erase a file that wont let me erase it? Dale Custer Computer Support 4 07-06-2003 09:48 AM



Advertisments