473,461 Members | 1,755 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

STL sort compare function problem

Hi. I have a problem using STL's built in sort that seems impossible
to get around.

if i have:
--------------------------------
struct object
{
int val;
}

void main()
{
vector<object> objects;
vector<int> indices;

sort(indices.begin(),indices.end(),compare)
}
--------------------------------

indices contains ints that refer to an index into the objects array

now, I want to sort the array "indices" based on the values in the
objects array that the integers in indices refer to. but i cannot
think of a legitimate compare funciton that could do this.

ideally i would have
bool compare(const int a, const int b, vector<object>& objects)
{
return(objects[a].val<objects[b].val)
}

but i cannot add that last parameter or i get compile problems.
"error C2064: term does not evaluate to a function taking 2 arguments"

does anyone know how to do this? thanks!

Oliver

Jul 23 '05 #1
8 16574
* laniik:
Hi. I have a problem using STL's built in sort that seems impossible
to get around.

if i have:
--------------------------------
struct object
{
int val;
}
Missing semicolon.

void main()
Invalid signature for 'main' -- see the C++ FAQ or (even better)
Bjarne Stroustrup's own FAQ.

{
vector<object> objects;
vector<int> indices;

sort(indices.begin(),indices.end(),compare)
}
--------------------------------

indices contains ints that refer to an index into the objects array

now, I want to sort the array "indices" based on the values in the
objects array that the integers in indices refer to. but i cannot
think of a legitimate compare funciton that could do this.

ideally i would have
bool compare(const int a, const int b, vector<object>& objects)
{
return(objects[a].val<objects[b].val)
}

but i cannot add that last parameter or i get compile problems.
"error C2064: term does not evaluate to a function taking 2 arguments"

does anyone know how to do this? thanks!


The comparison "function" can be an object that behaves like a function,
i.e. has an operator(). That kind of object is called a functor. And
a functor object can carry a pointer to the 'objects' vector.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 23 '05 #2
ok i did some research and am now introduced to the wonderful world of
functors, but its not entirely clear to me how this works.

i have a functor:
class compare
{
public:
vector<object>* objects;
bool operator ()(const int p1,const int p2)
{
return((*objects)[p1].x < (*objects)[p2].x);
}
};

and in my main
....
sort(indices.begin(),indices.end(),compare());
....

now this compiles fine, but the problem is that i have no clue how to
initiaize the pointer to the objects vector. I am not instantiating
the class when i pass it in the sort function, so I dont see how its
possible to set the pointer anywhere. Where can this be done?

thanks a lot for the help!

Oliver

Jul 23 '05 #3
* laniik:
ok i did some research and am now introduced to the wonderful world of
functors, but its not entirely clear to me how this works.

i have a functor:
class compare
{
public:
vector<object>* objects;
Style & safety: make the pointer 'private'.
bool operator ()(const int p1,const int p2)
{
return((*objects)[p1].x < (*objects)[p2].x);
}
More style & safety: make that member function 'const'.
};

and in my main
...
sort(indices.begin(),indices.end(),compare());
...

now this compiles fine, but the problem is that i have no clue how to
initiaize the pointer to the objects vector. I am not instantiating
the class when i pass it in the sort function, so I dont see how its
possible to set the pointer anywhere. Where can this be done?


The 'compare' class constructor.

class compare
{
private:
std::vector<object>* myPObjects;
public:
compare( std::vector<object>* p ): myPObjects( p ) {}
... as before
};

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 23 '05 #4
laniik wrote:
ok i did some research and am now introduced to the wonderful world of
functors, but its not entirely clear to me how this works.

i have a functor:
class compare
{
public:
vector<object>* objects;
bool operator ()(const int p1,const int p2)
{
return((*objects)[p1].x < (*objects)[p2].x);
}
};

and in my main
...
sort(indices.begin(),indices.end(),compare());
...

now this compiles fine, but the problem is that i have no clue how to
initiaize the pointer to the objects vector. I am not instantiating
the class when i pass it in the sort function, so I dont see how its
possible to set the pointer anywhere. Where can this be done?

thanks a lot for the help!

Oliver

#include <vector>
#include <algorithm>

struct object
{
int val;
};

class compare
{
public:
std::vector<object> * objects;

compare(std::vector<object>* obj) : objects(obj) {}

bool operator ()(const int p1,const int p2)
{
return((*objects)[p1].val < (*objects)[p2].val);
}
};

int main()
{
std::vector<object> objects;
std::vector<int> indices;

std::sort(indices.begin(),indices.end(),compare(&o bjects));

return 0;
}
Jul 23 '05 #5
laniik wrote:
ok i did some research and am now introduced to the wonderful world of
functors, but its not entirely clear to me how this works.

i have a functor:
class compare
{
public:
vector<object>* objects;
bool operator ()(const int p1,const int p2)
{
return((*objects)[p1].x < (*objects)[p2].x);
}
};

and in my main
...
sort(indices.begin(),indices.end(),compare());
...


Why use a pointer to the vector in your functor? Why
not use a reference?
class compare : public std::binary_function<int, int>
{
const std::vector<object>& objects;
public:
compare(const std::vector<object>& o) : objects(o) { }
inline bool operator()(const int p1, const int p2)
{
return (objects[p1].x < objects[p2].x);
}
};

//...
sort(indices.begin(), indices.end(), compare(objects));
//...
Jul 23 '05 #6
red floyd wrote:
laniik wrote:
ok i did some research and am now introduced to the wonderful world of
functors, but its not entirely clear to me how this works.

i have a functor:
class compare
{
public:
vector<object>* objects;
bool operator ()(const int p1,const int p2)
{
return((*objects)[p1].x < (*objects)[p2].x);
}
};

and in my main
...
sort(indices.begin(),indices.end(),compare());
...


Why use a pointer to the vector in your functor? Why
not use a reference?


The functor should ideally be stateless. And in fact it could be if the
indices vector stored iterators of the container holding objects,
instead of integer indices. For the indices vector to store iterators,
the iterators would have to be stable. Iterators for a vector do remain
valid most of the time, but increasing the size of a vector can
invalidate all of its iterators.

Since the indices vector already offers the benefits of vector storage,
why not change objects to a different type of container, one with
stable iterators? Doing so would make compare so simple it could become
just an ordinary function (if desired), and the whole implementation
would be more self-maintaining:

#include <vector>
#include <list>
#include <algorithm>

using std::vector;
using std::list;

struct object
{
int val;
};

bool
compare( const list<object>::iterator& i1,
const list<object>::iterator& i2 )
{
return (*i1).val < (*i2).val;
}

int main()
{
list<object> objects;
vector<list<object>::iterator> indices;

std::sort( indices.begin(), indices.end(), compare);

return 0;
}

Jul 23 '05 #7
* red floyd:

Why use a pointer to the vector in your functor? Why
not use a reference?


A reference is not copyable. Hence some compilers may complain about not
being able to generate an assignment operator. And many people (including
me) dislike such warnings, and also dislike writing more to avoid them.

A reference as an argument gives you an existence guarantee under the
assumption that the reference is not obtained by pointer dereferencing,
or the assumption that the rest of the program is correct C++, while a
reference as member does not give any such guarantee, so it has no
advantage that way.

On the other hand, a reference states in code that a null-reference is a
bug (it's invalid C++), unintended.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 23 '05 #8
* Greg:

The functor should ideally be stateless. And in fact it could be if the
indices vector stored iterators of the container holding objects,
instead of integer indices. For the indices vector to store iterators,
the iterators would have to be stable. Iterators for a vector do remain
valid most of the time, but [1] increasing the size of a vector can
invalidate all of its iterators.
In addition to that last point, (2) the current design decouples the 'indices'
from the 'objects' so that a given 'indices' can be used with any 'objects'
vector of sufficient size.

And, it may be that (3) that design is not in one's own code, but imposed by
existing, frozen code.

Since the indices vector already offers the benefits of vector storage,
why not change objects to a different type of container, one with
stable iterators? Doing so would make compare so simple it could become
just an ordinary function (if desired), and the whole implementation
would be more self-maintaining:


Barring (1), (2) or (3), or some other reason. ;-)

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 23 '05 #9

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

Similar topics

9
by: lawrence | last post by:
Is there an easy way to sort a 2 dimensional array alphabetically by the second field in each row? Also, when I use sort() on a two dimensional array, it seems to work a lot like...
4
by: its me | last post by:
Let's say I have a class of people... Public Class People Public Sex as String Public Age as int Public Name as string end class And I declare an array of this class...
7
by: Christopher Jeris | last post by:
I am relatively new to JavaScript, though not to programming, and I'm having trouble finding the idiomatic JS solution to the following problem. I have a table with (say) fields f1, f2, f3. I...
40
by: Elijah Bailey | last post by:
I want to sort a set of records using STL's sort() function, but dont see an easy way to do it. I have a char *data; which has size mn bytes where m is size of the record and n is the...
10
by: Paul Schneider | last post by:
I want to sort a class derived from std::vector with STL sort.: template<typename T, typename fitParaType, typename fitResType> class Manipulator{ // shouldn't I now be able to access private...
19
by: David | last post by:
Hi all, A while back I asked how to sort an array of strings which would have numerals and I wanted to put them in sequential numerical order. For example: myArray = "file1"; myArray =...
7
by: Angus Comber | last post by:
Hello Here is my code so far. Is this correct/incorrect/along the right lines/other? #include <stdio.h> #include <string.h> #include <search.h> struct mystruct {
1
by: Jason P Opdycke [MSFT] | last post by:
Hello All - I have 2 list boxes. Items in Left list box populated from a DB. I remove an item from the left box and add an item to the right box to allow user selection. When that item is...
2
by: Joe Fallon | last post by:
I have 2 listboxes on a Web Form. As I move an item from 1 to the other it shows up at the end of the list. How can I sort the list that just got the new item added to it so it is in alphabetical...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
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
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
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
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...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...
0
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...

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.