472,961 Members | 1,750 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

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

Problems with STL sorting using member functions

Good day.

I'm having trouble telling STL to use a member function to sort items
within the relevant class. The isLess() function needs to have access
to the private members of the Foo class to determine if the one item is
less than the other (it uses two vectors, one containing the actual
data, and one that stores IDs that index into the data vector). The
code below is pretty self-explanatory. I've looked into mem_fun, but
I'm stuck. The same general error seems to occur if I use other
<algorithmalgorithms ("find_if" etc), so it's not something specific
to STL's "sort", but rather on how to let it use the member function
correctly.

I'm using g++ (GCC) 3.4.4 (cygming special), and the error (if you were
to compile the code below) is:

In member function `void Foo::mySort()':
error: no matching function for call to
`sort(__gnu_cxx::__normal_iterator<int*, std::vector<int,
std::allocator<int >, __gnu_cxx::__normal_iterator<int*,
std::vector<int, std::allocator<int >, <unknown type>)'
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_algo.h:2576:
note: candidates are: void std::sort(_RandomAccessIterator,
_RandomAccessIterator, _Compare) [with _RandomAccessIterator =
__gnu_cxx::__normal_iterator<int*, std::vector<int, std::allocator<int>
, _Compare = bool (Foo::*)(int, int)]
If I rewrite:
sort(idList.begin(), idList.end(), isLess)

to read:
sort(idList.begin(), idList.end(), &Foo::isLess)

a long list of STL files (only stl_algo.h reproduced here) report the
following error:
/usr/lib/gcc/i686-pc-cygwin/3.4.4/include/c++/bits/stl_algo.h:124:
error: must use .* or ->* to call pointer-to-member function in `__comp
(...)'

Any help will be greatly appreciated.

Thanks!
#include <algorithm>
#include <functional>
#include <vector>

using namespace std;

class Foo {

public:

Foo() {

for (int i=0; i < 5; i++) {
myList.push_back(i*10);
idList.push_back(i);
}

random_shuffle(myList.begin(), myList.end());
}

bool isLess(int leftID, int rightID) {
return (myList[leftID] < myList[rightID]);
}

void mySort() {
sort(idList.begin(), idList.end(), isLess);
}

private:
vector<intmyList;
vector<intidList;

};

int main(int argc, char** argv) {

Foo myObj;
myObj.mySort();

return 0;
}

Aug 20 '06 #1
3 9785
Nelis Franken wrote:
Good day.

I'm having trouble telling STL to use a member function to sort items
within the relevant class. The isLess() function needs to have access
to the private members of the Foo class to determine if the one item is
less than the other (it uses two vectors, one containing the actual
data, and one that stores IDs that index into the data vector). The
code below is pretty self-explanatory. I've looked into mem_fun, but
I'm stuck. The same general error seems to occur if I use other
<algorithmalgorithms ("find_if" etc), so it's not something specific
to STL's "sort", but rather on how to let it use the member function
correctly.
STL is not your friend in this case, because you can't make a binary
member function to a ternary free function with it's means. So unless
you want to use boost, it's a specialised nested functor:

struct IsLess
{
IsLess(Foo const& self_)
: self(self_) { }

bool operator () (int leftID, int rightID) const {
return self.myList[leftID] < self.myList[rightID];
}

Foo const& self;
};

void mySort() {
sort(idList.begin(), idList.end(), IsLess(*this));
}

In boost, there some alternatives:

#include <boost/bind.hpp>

void mySort() {
sort(idList.begin(), idList.end(),
bind(&Foo::isLess, this, _1, _2));
}

or very similar the boost lambda library:

#include <boost/lambda/bind.hpp>

namespace bl = boost::lambda;

void mySort() {
sort(idList.begin(), idList.end(),
bind(&Foo::isLess, this, bl::_1, bl::_2));
}

or even without isLess:

void mySort() {
sort(idList.begin(), idList.end(),
bl::var(myList)[bl::_1] < bl::var(myList)[bl::_2]);
}

then

for_each(idList.begin(), idList.end(), cout << bl::_1);

prints

42310

The var in the more advanced use of boost::lambda is necessary to make
the compiler take boost::lambda's subscript operator rather than
std::vector's one. This is not an issue with most of the binary operators.

Jens
Aug 20 '06 #2
Thanks Jens!

Jens Theisen wrote:
Nelis Franken wrote:
Good day.

I'm having trouble telling STL to use a member function to sort items
within the relevant class. The isLess() function needs to have access
to the private members of the Foo class to determine if the one item is
less than the other (it uses two vectors, one containing the actual
data, and one that stores IDs that index into the data vector). The
code below is pretty self-explanatory. I've looked into mem_fun, but
I'm stuck. The same general error seems to occur if I use other
<algorithmalgorithms ("find_if" etc), so it's not something specific
to STL's "sort", but rather on how to let it use the member function
correctly.

STL is not your friend in this case, because you can't make a binary
member function to a ternary free function with it's means. So unless
you want to use boost, it's a specialised nested functor:

struct IsLess
{
IsLess(Foo const& self_)
: self(self_) { }

bool operator () (int leftID, int rightID) const {
return self.myList[leftID] < self.myList[rightID];
}

Foo const& self;
};

void mySort() {
sort(idList.begin(), idList.end(), IsLess(*this));
}

In boost, there some alternatives:

#include <boost/bind.hpp>

void mySort() {
sort(idList.begin(), idList.end(),
bind(&Foo::isLess, this, _1, _2));
}

or very similar the boost lambda library:

#include <boost/lambda/bind.hpp>

namespace bl = boost::lambda;

void mySort() {
sort(idList.begin(), idList.end(),
bind(&Foo::isLess, this, bl::_1, bl::_2));
}

or even without isLess:

void mySort() {
sort(idList.begin(), idList.end(),
bl::var(myList)[bl::_1] < bl::var(myList)[bl::_2]);
}

then

for_each(idList.begin(), idList.end(), cout << bl::_1);

prints

42310

The var in the more advanced use of boost::lambda is necessary to make
the compiler take boost::lambda's subscript operator rather than
std::vector's one. This is not an issue with most of the binary operators.

Jens
Aug 20 '06 #3
Nelis Franken wrote:
I'm having trouble telling STL to use a member function to sort items
within the relevant class. The isLess() function needs to have access
to the private members of the Foo class to determine if the one item
is less than the other (it uses two vectors, one containing the actual
data, and one that stores IDs that index into the data vector). [..]
You're trying to use non-static member function as a callback, essentially.
That's impossible. You need to use binders and mem_fun, but the problem is
that the standard mem_fun adapters do not adapt functions with more than
one argument. So, you could try a static function and pass the pointer to
your 'Foo' as its first argument, but then you have a function with three
arguments and standard binders don't work with functions with more than
two arguments.

Your solution is either use 'Boost's binders, or roll your own, or create
a "proxy" comparator, which will hold a reference to your 'Foo' object and
use it in its operator():

class Foo {
...
class ProxyLess {
Foo& that;
public:
ProxyLess(Foo& f) : that(f) {}
bool operator()(int leftID, int rightID) const {
return (that.myList[leftID] < that.myList[rightID]);
}
};

void mySort() {
sort(idList.begin(), idList.end(), ProxyLess(*this));
}
...
};

Also, naming your member 'List' and instead implement it using a vector
is misleading, considering that there is a standard 'list' template,
which you cannot sort using 'std::sort' function. Just an observation.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Aug 20 '06 #4

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

Similar topics

18
by: jblazi | last post by:
I should like to search certain characters in a string and when they are found, I want to replace other characters in other strings that are at the same position (for a very simply mastermind game)...
3
by: praba kar | last post by:
Dear All, I am new to Python. I am in need of some sorting functions (eg) numerical sorting functions and alphapetical sorting functions. I have searched through net But I cannot find any...
9
by: Hunter Hou | last post by:
Folks, I am just curious why standard library doesn't provide a "merge" operation without sorting, because sometimes I don't require sorting, just merge. I looked at list.merge() and merge()...
5
by: matthias_k | last post by:
Hi, I need to sort elements of a std::list using a function predicate, something like: bool predicate( const& M m1, const& M m2 ) { return m1.somedata < m2.somedata; } I tried to call...
4
by: Mark Travis | last post by:
Hi all, I have written a simple Web Application that displays a query result onto a page using the ASP DataGrid. To Digress ======= Development information about the page is as follows 1....
19
by: Owen T. Soroke | last post by:
Using VB.NET I have a ListView with several columns. Two columns contain integer values, while the remaining contain string values. I am confused as to how I would provide functionality to...
11
by: Jim Michaels | last post by:
friend fraction& operator+=(const fraction& rhs); fraction.h(64) Error: error: 'fraction& operator+=(const fraction&)' must take exactly two arguments I practically pulled this out of a C++...
11
by: Trent | last post by:
Running this I see that on first run, both bubble and selection sort have 9 sort counts while insertion sort has ZERO. With a sorted list, should this be ZERO for all? Also bsort and Ssort have...
3
KevinADC
by: KevinADC | last post by:
If you are entirely unfamiliar with using Perl to sort data, read the "Sorting Data with Perl - Part One and Two" articles before reading this article. Beginning Perl coders may find this article...
0
by: lllomh | last post by:
Define the method first this.state = { buttonBackgroundColor: 'green', isBlinking: false, // A new status is added to identify whether the button is blinking or not } autoStart=()=>{
2
by: DJRhino | last post by:
Was curious if anyone else was having this same issue or not.... I was just Up/Down graded to windows 11 and now my access combo boxes are not acting right. With win 10 I could start typing...
2
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 4 Oct 2023 starting at 18:00 UK time (6PM UTC+1) and finishing at about 19:15 (7.15PM) The start time is equivalent to 19:00 (7PM) in Central...
0
by: Aliciasmith | last post by:
In an age dominated by smartphones, having a mobile app for your business is no longer an option; it's a necessity. Whether you're a startup or an established enterprise, finding the right mobile app...
0
tracyyun
by: tracyyun | last post by:
Hello everyone, I have a question and would like some advice on network connectivity. I have one computer connected to my router via WiFi, but I have two other computers that I want to be able to...
2
by: giovanniandrean | last post by:
The energy model is structured as follows and uses excel sheets to give input data: 1-Utility.py contains all the functions needed to calculate the variables and other minor things (mentions...
3
NeoPa
by: NeoPa | last post by:
Introduction For this article I'll be using a very simple database which has Form (clsForm) & Report (clsReport) classes that simply handle making the calling Form invisible until the Form, or all...
3
by: nia12 | last post by:
Hi there, I am very new to Access so apologies if any of this is obvious/not clear. I am creating a data collection tool for health care employees to complete. It consists of a number of...
0
isladogs
by: isladogs | last post by:
The next online meeting of the Access Europe User Group will be on Wednesday 6 Dec 2023 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, Mike...

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.