473,399 Members | 3,302 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,399 software developers and data experts.

Using priority_queue

Is there any way to use a priority_queue with pointers? The reason why I
ask is that I want a data structure that contains pointers to objects, not
copies of objects. Also, I want them to be sorted by priority. On the same
note, then, is there a way to write an operator:

bool operator <(Foo* foo1, Foo* foo2);?

Inside the operator, the pointers would be dereferenced then compared. Is
it not possible to do this? If not, my solution would be to simply
dereference any pointers I had before comparing them. I also want to not
have to cast away const every time I pop something from my priority queue.
(On a side note, how expensive is casting in C++? I know in Java casting
too often can really rape your application's performance.) If I want
functionality like this, am I going to be required to make my own data
structure?
Jul 22 '05 #1
11 2056
On Fri, 16 Jul 2004 14:00:44 -0400, Aguilar, James
<jf**@cec.NOBOTSwustl.edu> wrote:
Is there any way to use a priority_queue with pointers?
Yes
The reason why I
ask is that I want a data structure that contains pointers to objects,
not
copies of objects. Also, I want them to be sorted by priority. On the
same
note, then, is there a way to write an operator:

bool operator <(Foo* foo1, Foo* foo2);?
No, you cannot overload operator for built in types. At least one of the
parameters must be a class.

Inside the operator, the pointers would be dereferenced then compared.
Is
it not possible to do this? If not, my solution would be to simply
dereference any pointers I had before comparing them. I also want to not
have to cast away const every time I pop something from my priority
queue.
(On a side note, how expensive is casting in C++? I know in Java casting
too often can really rape your application's performance.) If I want
functionality like this, am I going to be required to make my own data
structure?


Apart from dynamic_cast casting is very efficient in C++, most of the time
its a no-op, but even if the compiler has to apply some offset that is
worked out at compile time. I guess dynamic_cast is similar to Java, in
any case its a runtime computation.

Some priority_queue code (not tested, just to give you the idea)

#include <queue>
#include <functional>

struct CompareFooPtr : public std::binary_function<Foo*, Foo*, bool>
{
bool operator()(Foo* x, Foo* y) const
{
return *x < *y;
}
};

typedef std::priority_queue<Foo*, std::vector<Foo*>, CompareFooPtr>
MyQueue;

MyQueue a_queue;

john
Jul 22 '05 #2
On Fri, 16 Jul 2004 11:12:47 -0700, John Harrison wrote:
On Fri, 16 Jul 2004 14:00:44 -0400, Aguilar, James
(On a side note, how expensive is casting in C++? I know in Java
casting too often can really rape your application's performance.)
Apart from dynamic_cast casting is very efficient in C++, most of the
time its a no-op, but even if the compiler has to apply some offset that
is worked out at compile time.


Some casts do require code to be executed in order to complete the
conversion. The following program has three casts. It makes three
calls to three constructors for the conversions. (Compiled with the
infamous g++ 2.96.)

#include <iostream>

class A
{
public:
A() { std::cout << "A\n"; }

void foo() const {}
};

class B
{
public:

B() { std::cout << "B default\n"; }
B(A const &) { std::cout << "B(A)\n"; }

operator A() const
{
return A();
}

void foo() const {}
};

int main()
{
B b0;
A const & a = static_cast<A const &>(b0);

B const & b1 = static_cast<B const &>(a);

B const & b2 = (B)a;
}

Ali
Jul 22 '05 #3
On Fri, 16 Jul 2004 12:12:12 -0700, Ali Cehreli <ac******@yahoo.com> wrote:
On Fri, 16 Jul 2004 11:12:47 -0700, John Harrison wrote:
On Fri, 16 Jul 2004 14:00:44 -0400, Aguilar, James
(On a side note, how expensive is casting in C++? I know in Java
casting too often can really rape your application's performance.)

Apart from dynamic_cast casting is very efficient in C++, most of the
time its a no-op, but even if the compiler has to apply some offset that
is worked out at compile time.


Some casts do require code to be executed in order to complete the
conversion. The following program has three casts. It makes three
calls to three constructors for the conversions. (Compiled with the
infamous g++ 2.96.)

#include <iostream>

class A
{
public:
A() { std::cout << "A\n"; }

void foo() const {}
};

class B
{
public:

B() { std::cout << "B default\n"; }
B(A const &) { std::cout << "B(A)\n"; }
operator A() const
{
return A();
}

void foo() const {}
};

int main()
{
B b0;
A const & a = static_cast<A const &>(b0);
B const & b1 = static_cast<B const &>(a);

B const & b2 = (B)a;
}

Ali


OK good point. And as well there are casts from double to int etc. etc.
which also cause some code to be executed.

I was actually thinking only of casts from a pointer to one type to a
pointer to another releated type since that was the most similar to what
happens in Java, but I should have made that clear.

john
Jul 22 '05 #4
"John Harrison" <jo*************@hotmail.com> wrote in message
news:opsa8svlpw212331@andronicus...
On Fri, 16 Jul 2004 14:00:44 -0400, Aguilar, James
<jf**@cec.NOBOTSwustl.edu> wrote:

[snip]


So, last question, I think. In the example you provided, do I still have to
cast away const?
Jul 22 '05 #5
On Fri, 16 Jul 2004 20:08:09 -0400, Aguilar, James
<jf**@cec.NOBOTSwustl.edu> wrote:
"John Harrison" <jo*************@hotmail.com> wrote in message
news:opsa8svlpw212331@andronicus...
On Fri, 16 Jul 2004 14:00:44 -0400, Aguilar, James
<jf**@cec.NOBOTSwustl.edu> wrote:

[snip]


So, last question, I think. In the example you provided, do I still
have to
cast away const?


Sorry I missed that. Why do you think you are going to have to cast away
const? I don't see the need.

john
Jul 22 '05 #6
"John Harrison" <jo*************@hotmail.com> wrote in message
news:opsa9qr3jt212331@andronicus...
On Sat, 17 Jul 2004 02:16:06 -0400, Aguilar, James
<jf**@cec.NOBOTSwustl.edu> wrote:
"John Harrison" <jo*************@hotmail.com> wrote in message
news:opsa9ks8fh212331@andronicus...
On Fri, 16 Jul 2004 20:08:09 -0400, Aguilar, James
<jf**@cec.NOBOTSwustl.edu> wrote:

> "John Harrison" <jo*************@hotmail.com> wrote in message
> news:opsa8svlpw212331@andronicus...
>> On Fri, 16 Jul 2004 14:00:44 -0400, Aguilar, James
>> <jf**@cec.NOBOTSwustl.edu> wrote:
>>
>> [snip]
>
> So, last question, I think. In the example you provided, do I still
> have to
> cast away const?
>
>

Sorry I missed that. Why do you think you are going to have to cast away const? I don't see the need.

john


Because after I get the object and run its activate method, I want to
delete
it. But, I might be confused. What would be considered const, the
pointer,
or the thing it was pointing to? How can I tell?


Well in the code I wrote nothing is const, so you shouldn't have any
problem deleting pointers extracted from the queue.

I still don't really see why you think const is an issue at all.


Earlier, when I was passing in objects, I was using this to get them out of
the queue:

Event* retEvnt = &(evntQ->top());
evntQ->pop();
return retEvnt;

However, it kept giving me errors to the effect of not being able to convert
from const Event to Event*. Hence, I assumed that the method top() returned
const T where T is the class in the queue. Looking at the queue header
confirms this:

/**
* Returns a read-only (constant) reference to the data at the first
* element of the %queue.
*/
const_reference
top() const { return c.front(); }

However, I need to delete this object when I'm done with it. I guess this
is not an issue since the object in the data structure is not the same as
the original object anyway. But, if the pointer is const, doesn't that mean
that I can't edit what it points to?
Jul 22 '05 #7
On Sat, 17 Jul 2004 10:47:28 -0400, Aguilar, James
<jf**@cec.NOBOTSwustl.edu> wrote:
"John Harrison" <jo*************@hotmail.com> wrote in message
news:opsa9qr3jt212331@andronicus...
On Sat, 17 Jul 2004 02:16:06 -0400, Aguilar, James
<jf**@cec.NOBOTSwustl.edu> wrote:
> "John Harrison" <jo*************@hotmail.com> wrote in message
> news:opsa9ks8fh212331@andronicus...
>> On Fri, 16 Jul 2004 20:08:09 -0400, Aguilar, James
>> <jf**@cec.NOBOTSwustl.edu> wrote:
>>
>> > "John Harrison" <jo*************@hotmail.com> wrote in message
>> > news:opsa8svlpw212331@andronicus...
>> >> On Fri, 16 Jul 2004 14:00:44 -0400, Aguilar, James
>> >> <jf**@cec.NOBOTSwustl.edu> wrote:
>> >>
>> >> [snip]
>> >
>> > So, last question, I think. In the example you provided, do I

still
>> > have to
>> > cast away const?
>> >
>> >
>>
>> Sorry I missed that. Why do you think you are going to have to cast away >> const? I don't see the need.
>>
>> john
>
> Because after I get the object and run its activate method, I want to
> delete
> it. But, I might be confused. What would be considered const, the
> pointer,
> or the thing it was pointing to? How can I tell?
>


Well in the code I wrote nothing is const, so you shouldn't have any
problem deleting pointers extracted from the queue.

I still don't really see why you think const is an issue at all.


Earlier, when I was passing in objects, I was using this to get them out
of
the queue:

Event* retEvnt = &(evntQ->top());
evntQ->pop();
return retEvnt;

However, it kept giving me errors to the effect of not being able to
convert
from const Event to Event*. Hence, I assumed that the method top()
returned
const T where T is the class in the queue. Looking at the queue header
confirms this:

/**
* Returns a read-only (constant) reference to the data at the first
* element of the %queue.
*/
const_reference
top() const { return c.front(); }

However, I need to delete this object when I'm done with it. I guess
this
is not an issue since the object in the data structure is not the same as
the original object anyway. But, if the pointer is const, doesn't that
mean
that I can't edit what it points to?


You are confusing different levels of const. In this queue

std::priority_queue<Foo>

it is true that top() return Foo const& (or, same thing, const Foo&) and
therefore you cannot use top() to modify the Foo object in the queue. But
in this queue

std::priority_queue<Foo*>

top() now returns Foo* const&. That is a const reference to the pointer,
but the Foo object itself is not const. In other words since your queue is
now storing pointers you cannot use top() to modify the pointer itself but
there is nothing stopping you modifying what the pointer is pointing at
(or deleting the pointer).

Basically the elements of a priority_queue are non modifyable while they
are in the queue, but if the elements are pointers, then it is the
pointers themselves that are const, not what they are pointing to.

john
Jul 22 '05 #8

"John Harrison" <jo*************@hotmail.com> wrote in message
news:opsbaetblz212331@andronicus...
[snip]


Fantastic. Thank you very much.
Jul 22 '05 #9
[...]
#include <iostream>

class A
{
public:
A() { std::cout << "A\n"; }

void foo() const {}
};

class B
{
public:

B() { std::cout << "B default\n"; }
B(A const &) { std::cout << "B(A)\n"; }

operator A() const
{
return A();
}

void foo() const {}
};

int main()
{
B b0;
A const & a = static_cast<A const &>(b0);
For the uninitiated, yours truly. Could you shed light on how the
abovementioned line results in a call to operator A()? I've perused
function objects in Josuttis and have dealt with them on a relatively
minor scale so I'm 'acclimated' with the concept.
I'm not grasping how the cast of b0 to an A const reference results in
the call to operator A(). (ie. A const& a = operator A()).
I need to revisit the four flavors of C++ casts, but for UDT's; isn't
a reinterpret_cast preferred?

B const & b1 = static_cast<B const &>(a);
B const & b2 = (B)a;

'(B)a' is essentially a C style cast?

Thanks for your time
Jul 22 '05 #10
On Sat, 17 Jul 2004 07:47:28 -0700, Aguilar, James wrote:
However, I need to delete this object when I'm done with it. [...] But, if the pointer is const,
doesn't that mean that I can't edit what it points to?


If the pointer is const, you can not change *the pointer*.

Still, you can delete the object that the pointer points to:

int const * p = new int(42);
delete p;

int * const q = new int(42);
delete q;

int const * const r = new int(42);
delete r;

They all have different constness, but we can delete the objects they
point to.

Ali
Jul 22 '05 #11
On Sat, 17 Jul 2004 15:37:24 -0700, ma740988 wrote:
[...]
#include <iostream>

class A
{
public:
A() { std::cout << "A\n"; }

void foo() const {}
};

class B
{
public:

B() { std::cout << "B default\n"; }
B(A const &) { std::cout << "B(A)\n"; }

operator A() const
{
return A();
}

void foo() const {}
};

int main()
{
B b0;
A const & a = static_cast<A const &>(b0);
Could you shed light on how the
abovementioned line results in a call to operator A()?


There is an explicit request for a type conversion from a 'B' to 'A
const &' and 'B::operator A()' fits the bill.

Actually, the cast is not needed at all in this case. The following
produces the same result:

A const & a = b0;
I've perused
function objects in Josuttis and have dealt with them on a relatively
minor scale so I'm 'acclimated' with the concept. I'm not grasping how
the cast of b0 to an A const reference results in the call to operator
A(). (ie. A const& a = operator A()).
B defines a 'operator A()' function that is supposed to be called in
any place where a B is used as an A. It is a conversion from a B to an
A.
I need to revisit the four
flavors of C++ casts, but for UDT's; isn't a reinterpret_cast preferred?


No, reinterpret_cast is platform dependent. It is the closest thing to
a C style cast but better; because it at least performs some tests at
compile time.

For many UDT conversions, no cast is needed. When the type is know at
compile time, a static_cast would be better.
B const & b1 = static_cast<B const &>(a);
B const & b2 = (B)a;

'(B)a' is essentially a C style cast?


Yes. There is a temporary B created as a result of that cast; but
don't ask me whether that temporary is an rvalue or an lvalue. :)

Ali
Jul 22 '05 #12

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

Similar topics

4
by: Tino | last post by:
Hopefully a simple question: What is the best/safest/fastest way to clear/make empty a std::priority_queue? Thanks, Ryan
16
by: newsock | last post by:
What differences between queue, deque and priority_queue? And under what situations choose one of them to use? Thanks for your help!
6
by: alexhong2001 | last post by:
Does "std::sort" work only with sequence containers, not associative containers at all? Among sequential containers, can it be used with "list", "queue" and other sequence containers besides...
7
by: Dave | last post by:
Hello all, I'm pondering why the default underlying container for std::priority_queue<> is std::vector<>. It would seem that inserts are liable to happen anywhere, which would make std::list<>...
18
by: J.M. | last post by:
I would like to use a data structure (e.g. from the STL) that always allows me to retrieve the largest element. (I want to push in elements, and remove the largest, push in further elements, etc.)...
1
by: mistersteve | last post by:
Alright guys, so I'm writting in c++ and I have an instance of the priority_queue class which i am filling with instances of this structure: struct app { int idTag; int date, hours,...
16
by: Ray | last post by:
Hi all, After many years of C, I thought I'd move to C++ recently. I think because I think in C, I'm coming to a misunderstanding of something. I've created a class foo which contains a...
8
by: thomas | last post by:
priority_queue usually uses the greater<intpredicate function. But as you know, we don't always use priority_queue<int>. Actually we may need the "priority_queue<pair<int,int>,...
24
by: Joe, G.I. | last post by:
Can anyone help me w/ a priority_queue. I'm generating MyEvent classes and I put them on a priority_queue, but I don't know how to get them in priority. The priority is the event w/ the smallest...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.