473,320 Members | 1,949 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

Finding an object in a <set> of pointers to objects

Hi

I need to maintain a <setof pointers to objects, and it must be
sorted based on the values of pointed objects, not pointer values. I
can achieve this easily by defining my own comparing predicate for the
<set>. Here is an example:

#include <string>
#include <set>
using namespace std;

class A
{
public:
A(const string& Name): m_Name(Name) {}
const string& Name() const { return m_Name; }

private:
string m_Name;

// Other members
// ...
};

class ptr_less
{
public:
bool operator()(const A* lhs, const A* rhs) const
{
return lhs->Name() < rhs->Name();
}
};

int main()
{
const string Names[] = { "alpha", "omega", "gamma", "beta",
"epsilon" };

// Create objects and fill 'S'
set<A*, ptr_lessS;
for (unsigned i = 0; i < sizeof(Names)/sizeof(Names[0]); ++i)
S.insert(new A(Names[i]));

// Use 'S' ...

// Delete objects in 'S'
set<A*, ptr_less>::const_iterator csi;
for (csi = S.begin(); csi != S.end(); ++csi)
delete *csi;
};

In this example pointers in the <setS will be sorted according to the
ascending order of names of pointed objects.

Now I want to find an obect in 'S' with name "gamma". How must I do
that? One way is to construct a dummy object with that name, and pass
its address to 'find' method of <set>. Here is an example:

A tempA("gamma");
S.find(&tempA);

Everything works ok, but creating a dummy object only for searching
purposes looks somewhat silly. Isn't there an elegant way to accomplish
this?

Thanks in advance

Martin

Nov 14 '06 #1
6 4675
Martin wrote:
Hi

I need to maintain a <setof pointers to objects, and it must be
sorted based on the values of pointed objects, not pointer values. I
can achieve this easily by defining my own comparing predicate for the
<set>.
[snip]
In this example pointers in the <setS will be sorted according to the
ascending order of names of pointed objects.

Now I want to find an obect in 'S' with name "gamma". How must I do
that? One way is to construct a dummy object with that name, and pass
its address to 'find' method of <set>. Here is an example:

A tempA("gamma");
S.find(&tempA);

Everything works ok, but creating a dummy object only for searching
purposes looks somewhat silly. Isn't there an elegant way to accomplish
this?
AFAIK, no. If you use a container like set, you're basically limited to
the interface exposed by the class. All of the binary search-like
operations on a set require arguments of the key type, so you basically
have to construct that dummy object. Of course there's nothing stopping
you from writing your own function that will do the work of creating the
dummy object behind the scenes: you can derive from std::set, wrap it in
another class, or even write a free fcn. for this.
Nov 14 '06 #2

Martin wrote:
Hi

I need to maintain a <setof pointers to objects, and it must be
sorted based on the values of pointed objects, not pointer values. I
can achieve this easily by defining my own comparing predicate for the
<set>. Here is an example:

#include <string>
#include <set>
using namespace std;

class A
{
public:
A(const string& Name): m_Name(Name) {}
const string& Name() const { return m_Name; }

private:
string m_Name;

// Other members
// ...
};

class ptr_less
{
public:
bool operator()(const A* lhs, const A* rhs) const
{
return lhs->Name() < rhs->Name();
}
};

int main()
{
const string Names[] = { "alpha", "omega", "gamma", "beta",
"epsilon" };

// Create objects and fill 'S'
set<A*, ptr_lessS;
for (unsigned i = 0; i < sizeof(Names)/sizeof(Names[0]); ++i)
S.insert(new A(Names[i]));

// Use 'S' ...

// Delete objects in 'S'
set<A*, ptr_less>::const_iterator csi;
for (csi = S.begin(); csi != S.end(); ++csi)
delete *csi;
};

In this example pointers in the <setS will be sorted according to the
ascending order of names of pointed objects.

Now I want to find an obect in 'S' with name "gamma". How must I do
that? One way is to construct a dummy object with that name, and pass
its address to 'find' method of <set>. Here is an example:

A tempA("gamma");
S.find(&tempA);

Everything works ok, but creating a dummy object only for searching
purposes looks somewhat silly. Isn't there an elegant way to accomplish
this?
I recommend using a smart pointer that can sort by the pointee.
The following smart pointer can do just that:
http://axter.com/smartptr/

Moreover, by using a smart pointer, you don't have to worry about
memory leaks, since the smart pointer will delete the object
automatically.

Nov 14 '06 #3

Martin wrote:
Hi

I need to maintain a <setof pointers to objects, and it must be
sorted based on the values of pointed objects, not pointer values. I
can achieve this easily by defining my own comparing predicate for the
<set>. Here is an example:

#include <string>
#include <set>
using namespace std;

class A
{
public:
A(const string& Name): m_Name(Name) {}
const string& Name() const { return m_Name; }

private:
string m_Name;

// Other members
// ...
};

class ptr_less
{
public:
bool operator()(const A* lhs, const A* rhs) const
{
return lhs->Name() < rhs->Name();
}
};

int main()
{
const string Names[] = { "alpha", "omega", "gamma", "beta",
"epsilon" };

// Create objects and fill 'S'
set<A*, ptr_lessS;
for (unsigned i = 0; i < sizeof(Names)/sizeof(Names[0]); ++i)
S.insert(new A(Names[i]));

// Use 'S' ...

// Delete objects in 'S'
set<A*, ptr_less>::const_iterator csi;
for (csi = S.begin(); csi != S.end(); ++csi)
delete *csi;
};

In this example pointers in the <setS will be sorted according to the
ascending order of names of pointed objects.

Now I want to find an obect in 'S' with name "gamma". How must I do
that? One way is to construct a dummy object with that name, and pass
its address to 'find' method of <set>. Here is an example:

A tempA("gamma");
S.find(&tempA);

Everything works ok, but creating a dummy object only for searching
purposes looks somewhat silly. Isn't there an elegant way to accomplish
this?
No, you need the dummy. Whats more, is you need op==(...).
Which can get nasty if you...say...use smart pointers.
Thankfully, boost::shared_ptr is equipped with an op== overload to
pointee.
So load the dummy into a smart pointer. and voila!

Another option is a std::map< A, shared_ptr<A in which case the key
can uses the default predicate. If i were you, i'ld go that way.

#include <iostream>
#include <set>
#include <iterator>
#include <boost/shared_ptr.hpp>

class A
{
std::string m_Name;
public:
A(const std::string& Name): m_Name(Name) {}
A(const A& copy) { m_Name = copy.m_Name; }
const std::string& Name() const { return m_Name; }
friend std::ostream&
operator<<(std::ostream& os, const A& r_a)
{
return os << r_a.m_Name;
}
};

typedef boost::shared_ptr< A SharedPtrA;

class ptr_less
{
public:
bool operator()(const SharedPtrA& lhs,
const SharedPtrA& rhs) const
{
return lhs->Name() < rhs->Name();
}
};

int main()
{
const char* Names[] = { "alpha",
"omega",
"gamma",
"beta",
"epsilon" };

// Create objects and fill 'S'
std::set< SharedPtrA, ptr_less S;
for (size_t i = 0; i < sizeof(Names)/sizeof(*Names); ++i)
{
A a(Names[i]);
S.insert( SharedPtrA(new A(a)) );
std::cout << a << std::endl;
}

typedef std::set< SharedPtrA, ptr_less >::iterator SIter;
SIter siter = S.find(SharedPtrA(new A("gamma")));
if(siter != S.end())
{
std::cout << "found = " << *(*siter);
std::cout << " at " << *siter << std::endl;
}
else
{
std::cout << "name not found!\n";
}
}

/*
alpha
omega
gamma
beta
epsilon
found = gamma at 0x5051a0
*/

Nov 14 '06 #4
Salt_Peter wrote:
Martin wrote:
>Hi

I need to maintain a <setof pointers to objects, and it must be
sorted based on the values of pointed objects, not pointer values. I
can achieve this easily by defining my own comparing predicate for the
<set>. Here is an example:
....
>>
In this example pointers in the <setS will be sorted according to the
ascending order of names of pointed objects.

Now I want to find an obect in 'S' with name "gamma". How must I do
that? One way is to construct a dummy object with that name, and pass
its address to 'find' method of <set>. Here is an example:

A tempA("gamma");
S.find(&tempA);

Everything works ok, but creating a dummy object only for searching
purposes looks somewhat silly. Isn't there an elegant way to accomplish
this?

No, you need the dummy. Whats more, is you need op==(...).
Which can get nasty if you...say...use smart pointers.
Thankfully, boost::shared_ptr is equipped with an op== overload to
pointee.
So load the dummy into a smart pointer. and voila!
Why do you say he needs op==? In a std::set, two keys are equal if
neither compares less than the other.
Nov 14 '06 #5
Mark P wrote:
Salt_Peter wrote:
Martin wrote:
Hi

I need to maintain a <setof pointers to objects, and it must be
sorted based on the values of pointed objects, not pointer values. I
can achieve this easily by defining my own comparing predicate for the
<set>. Here is an example:
...
>
In this example pointers in the <setS will be sorted according to the
ascending order of names of pointed objects.

Now I want to find an obect in 'S' with name "gamma". How must I do
that? One way is to construct a dummy object with that name, and pass
its address to 'find' method of <set>. Here is an example:

A tempA("gamma");
S.find(&tempA);

Everything works ok, but creating a dummy object only for searching
purposes looks somewhat silly. Isn't there an elegant way to accomplish
this?
No, you need the dummy. Whats more, is you need op==(...).
Which can get nasty if you...say...use smart pointers.
Thankfully, boost::shared_ptr is equipped with an op== overload to
pointee.
So load the dummy into a smart pointer. and voila!

Why do you say he needs op==? In a std::set, two keys are equal if
neither compares less than the other.
Because find requires it. Ordering relation is not the same as the
equivalence relation.

Keys are equal depending on what "equal" means to the programmer. The
keys here are pointers and the pointer's value is *not* used to order
the set.
The pointers are ordered by the values held by a pointee's member.
Which itself needs to be unique to satisfy the set's requirements.
Consider that all initialized allocation pointers are unique except for
Null pointers. Thats the OP's issue. How do you load and compare the
dummy for equivalence?
Shared_ptr solves that issue because it has an op== that compares the
dereferenced values for equality. You could overload an op== to compare
A& dummy and a shared_ptr< A >&, but there is no need to, just load the
dummy in a shared_ptr and voila!.

Nov 14 '06 #6
Salt_Peter wrote:
Mark P wrote:
>Salt_Peter wrote:
>>Martin wrote:
Hi

I need to maintain a <setof pointers to objects, and it must be
sorted based on the values of pointed objects, not pointer values. I
can achieve this easily by defining my own comparing predicate for the
<set>. Here is an example:
...
>>>In this example pointers in the <setS will be sorted according to the
ascending order of names of pointed objects.

Now I want to find an obect in 'S' with name "gamma". How must I do
that? One way is to construct a dummy object with that name, and pass
its address to 'find' method of <set>. Here is an example:

A tempA("gamma");
S.find(&tempA);

Everything works ok, but creating a dummy object only for searching
purposes looks somewhat silly. Isn't there an elegant way to accomplish
this?
No, you need the dummy. Whats more, is you need op==(...).
Which can get nasty if you...say...use smart pointers.
Thankfully, boost::shared_ptr is equipped with an op== overload to
pointee.
So load the dummy into a smart pointer. and voila!
Why do you say he needs op==? In a std::set, two keys are equal if
neither compares less than the other.

Because find requires it. Ordering relation is not the same as the
equivalence relation.
No it doesn't and, for a std::set, yes it is.
Nov 15 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Francesco Moi | last post by:
Hello. I'm trying to build a RSS feed for my website. It starts: ----------------//--------------------- <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE rss PUBLIC "-//Netscape...
8
by: ASP Yaboh | last post by:
I have an ArrayList of data gathered from a database. I want to create a web page from this data by creating a <table>, each cell in each row displays the appropriate data. One of those cells in...
1
by: aaa | last post by:
I am using a third party provider for Travel related web services. These services are not very well documented and I am having to wing my way thru nearly every one. Some I can pull data from...
5
by: Kunal | last post by:
I'm unable to use the "xsd:all" tag in derived objects, in a hierarchical schema setup. For example, I have the following schema (that doesn't validate with XMLSpy): (UserOfDerived extends...
16
by: barcaroller | last post by:
I have a map<T*that stores pointers to objects. How can I tell map<T*to use the objects' operator<() and not the value of the pointers for sorting? If that's not feasible, what alternatives do...
7
by: Nathan Sokalski | last post by:
Something that I recently noticed in IE6 (I don't know whether it is true for other browsers or versions of IE) is that it renders <br/and <br></br> differently. With the <br/version, which is what...
10
by: REH | last post by:
Is it well defined to use a std::set of pointers? I ask because of the restrictions on using relational operators with pointers. Does a set of pointers suffer from the same restrictions, or does...
5
by: BobRoyAce | last post by:
There is a web page that has a bunch of links on it (i.e. "<A HREF=..."). I am trying to automate clicking on one in a WebBrowser control. However when I execute the following code: Dim...
0
by: DolphinDB | last post by:
The formulas of 101 quantitative trading alphas used by WorldQuant were presented in the paper 101 Formulaic Alphas. However, some formulas are complex, leading to challenges in calculation. Take...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.