473,385 Members | 1,359 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,385 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 9832
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...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
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...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 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 former...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
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
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...

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.