473,395 Members | 1,631 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,395 software developers and data experts.

problem on creating functor for std::sort

lok
i have a class:

template <class T1, class T2>
class CPairMapping {
public:
typedef std::pair<T1, T2> ValuePair_t;
typedef std::vector<ValuePair_t> ValueList_t;
typedef std::binary_function< ValuePair_t, ValuePair_t, bool> ValuePair_IsLess;

void SortAscend(const ValuePair_IsLess& isLess_) {
std::sort(Map.begin(), Map.end(), isLess_);
}

// skip other funciton like add,delete,lookup...
protected:
ValueList_t Map;
};

i want to sort the Map with a functor supplied by the caller of SortAscend()
i created a functor:
typedef COne2ManyMapping<int, int> INT2INTMap;
class INT2INTMap_IsLess: public INT2INTMap::ValuePair_IsLess {
public:
bool operator() (INT2INTMap::ValuePair_t lhs_,INT2INTMap::ValuePair_t rhs_)
{
return true;
}
};

up to now, no compile or link error
but if i call the SortAscend loke this:
INT2INTMap a;
a.AddEntry(1, 2);
a.AddEntry(3, 4);
a.SortAscend( INT2INTMap_IsLess() );

my vc++ 6.0 compiler reported:
error C2064: term does not evaluate to a function
see reference to function template instantiation '
void __cdecl std::_Unguarded_insert(
struct std::pair<int,int> *,
struct std::pair<int,int>,
struct std::binary_function<
struct std::pair<int,int>,
struct std::pair<int,int>,
bool

)
' being compiled

what is the problem ?
thx
Jul 22 '05 #1
8 3475
lok wrote:
i have a class:

template <class T1, class T2>
class CPairMapping {
public:
typedef std::pair<T1, T2> ValuePair_t;
typedef std::vector<ValuePair_t> ValueList_t;
typedef std::binary_function< ValuePair_t, ValuePair_t, bool>
ValuePair_IsLess;

void SortAscend(const ValuePair_IsLess& isLess_) {
std::sort(Map.begin(), Map.end(), isLess_);
}

// skip other funciton like add,delete,lookup...
protected:
ValueList_t Map;
};

i want to sort the Map with a functor supplied by the caller of
SortAscend()
i created a functor:
typedef COne2ManyMapping<int, int> INT2INTMap;
class INT2INTMap_IsLess: public INT2INTMap::ValuePair_IsLess {
public:
bool operator() (INT2INTMap::ValuePair_t
lhs_,INT2INTMap::ValuePair_t rhs_)
{
return true;
}
};

up to now, no compile or link error
but if i call the SortAscend loke this:
INT2INTMap a;
a.AddEntry(1, 2);
a.AddEntry(3, 4);
a.SortAscend( INT2INTMap_IsLess() );

my vc++ 6.0 compiler reported:
error C2064: term does not evaluate to a function
see reference to function template instantiation '
void __cdecl std::_Unguarded_insert(
struct std::pair<int,int> *,
struct std::pair<int,int>,
struct std::binary_function<
struct std::pair<int,int>,
struct std::pair<int,int>,
bool

)
' being compiled

what is the problem ?


Your operator() is not const, so it isn't considered when std::sort
tries to call your function object.

Jul 22 '05 #2
lok

"Rolf Magnus" <ra******@t-online.de> wrote in message
news:bq*************@news.t-online.com...
lok wrote:
i have a class:

template <class T1, class T2>
class CPairMapping {
public:
typedef std::pair<T1, T2> ValuePair_t;
typedef std::vector<ValuePair_t> ValueList_t;
typedef std::binary_function< ValuePair_t, ValuePair_t, bool>
ValuePair_IsLess;

void SortAscend(const ValuePair_IsLess& isLess_) {
std::sort(Map.begin(), Map.end(), isLess_);
}

// skip other funciton like add,delete,lookup...
protected:
ValueList_t Map;
};

i want to sort the Map with a functor supplied by the caller of
SortAscend()
i created a functor:
typedef COne2ManyMapping<int, int> INT2INTMap;
class INT2INTMap_IsLess: public INT2INTMap::ValuePair_IsLess {
public:
bool operator() (INT2INTMap::ValuePair_t
lhs_,INT2INTMap::ValuePair_t rhs_)
{
return true;
}
};

up to now, no compile or link error
but if i call the SortAscend loke this:
INT2INTMap a;
a.AddEntry(1, 2);
a.AddEntry(3, 4);
a.SortAscend( INT2INTMap_IsLess() );

my vc++ 6.0 compiler reported:
error C2064: term does not evaluate to a function
see reference to function template instantiation '
void __cdecl std::_Unguarded_insert(
struct std::pair<int,int> *,
struct std::pair<int,int>,
struct std::binary_function<
struct std::pair<int,int>,
struct std::pair<int,int>,
bool

)
' being compiled

what is the problem ?


Your operator() is not const, so it isn't considered when std::sort
tries to call your function object.


thx for your rely

i changed the operator() to this:
bool operator() (INT2INTMap::ValuePair_t lhs_,INT2INTMap::ValuePair_t rhs_)
const
{
return true;
}

the same error still occured
Jul 22 '05 #3
lok wrote in news:69**************************@posting.google.c om:
i have a class:

template <class T1, class T2>
class CPairMapping {
public:
typedef std::pair<T1, T2> ValuePair_t;
typedef std::vector<ValuePair_t> ValueList_t;
typedef std::binary_function< ValuePair_t, ValuePair_t, bool>
ValuePair_IsLess;

void SortAscend(const ValuePair_IsLess& isLess_) {
std::sort(Map.begin(), Map.end(), isLess_);
This isn't going to work std::binary_function< > isn't a binary function
its a base class for function object's that *only* supplies some
typedef's that describe the arguments and return values.

It does *NOT* have a virtual operator () (T const &, T const &) const.

You need to pass std::sort() a genuine functor.

std::less< ValuePair_t >() would be a good start.

std::sort(Map.begin(), Map.end(), std::less< ValuePair_t >() );

}

// skip other funciton like add,delete,lookup...
protected:
ValueList_t Map;
};

i want to sort the Map with a functor supplied by the caller of
SortAscend()

You can a make SortAscend() a template member function (uppgrade your
compiler first) or make a functor with a virtual operator () ...


i created a functor:
typedef COne2ManyMapping<int, int> INT2INTMap;
class INT2INTMap_IsLess: public INT2INTMap::ValuePair_IsLess {
public:
bool operator() (INT2INTMap::ValuePair_t
lhs_,INT2INTMap::ValuePair_t rhs_) {
return true;
}
};
Make operator () a const member, also unless you like writing programmes
that hang or crash make it a valid Ordering function (model a < b) simply
returning true is nonsence.

std::sort(Map.begin(), Map.end(), INT2INTMap_IsLess() );

up to now, no compile or link error
but if i call the SortAscend loke this:
INT2INTMap a;
a.AddEntry(1, 2);
a.AddEntry(3, 4);
a.SortAscend( INT2INTMap_IsLess() );

my vc++ 6.0 compiler reported:
error C2064: term does not evaluate to a function
Yup std::binary_function<> isn't a functor.
see reference to function template instantiation '
void __cdecl std::_Unguarded_insert(
struct std::pair<int,int> *,
struct std::pair<int,int>,
struct std::binary_function<
struct std::pair<int,int>,
struct std::pair<int,int>,
bool
>

)
' being compiled


HTH.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #4
lok

"Rob Williscroft" <rt*@freenet.REMOVE.co.uk> wrote in message
news:Xn**********************************@195.129. 110.130...
lok wrote in news:69**************************@posting.google.c om:
i have a class:

template <class T1, class T2>
class CPairMapping {
public:
typedef std::pair<T1, T2> ValuePair_t;
typedef std::vector<ValuePair_t> ValueList_t;
typedef std::binary_function< ValuePair_t, ValuePair_t, bool>
ValuePair_IsLess;

void SortAscend(const ValuePair_IsLess& isLess_) {
std::sort(Map.begin(), Map.end(), isLess_);
This isn't going to work std::binary_function< > isn't a binary function
its a base class for function object's that *only* supplies some
typedef's that describe the arguments and return values.

It does *NOT* have a virtual operator () (T const &, T const &) const.

You need to pass std::sort() a genuine functor.

std::less< ValuePair_t >() would be a good start.

std::sort(Map.begin(), Map.end(), std::less< ValuePair_t >() );


thx for your reply
i realize the problem (though not completely understand...)
but i need my own less comparison (that's why i want to create a
INT2INTMap_IsLess functor)

}

// skip other funciton like add,delete,lookup...
protected:
ValueList_t Map;
};

i want to sort the Map with a functor supplied by the caller of
SortAscend()

You can a make SortAscend() a template member function (uppgrade your
compiler first) or make a functor with a virtual operator () ...


i think this is the direction to go
can u explain further ? thx


i created a functor:
typedef COne2ManyMapping<int, int> INT2INTMap;
class INT2INTMap_IsLess: public INT2INTMap::ValuePair_IsLess {
public:
bool operator() (INT2INTMap::ValuePair_t
lhs_,INT2INTMap::ValuePair_t rhs_) {
return true;
}
};
Make operator () a const member, also unless you like writing programmes
that hang or crash make it a valid Ordering function (model a < b) simply
returning true is nonsence.


it just a test code to make the code more simple


std::sort(Map.begin(), Map.end(), INT2INTMap_IsLess() );

up to now, no compile or link error
but if i call the SortAscend loke this:
INT2INTMap a;
a.AddEntry(1, 2);
a.AddEntry(3, 4);
a.SortAscend( INT2INTMap_IsLess() );

my vc++ 6.0 compiler reported:
error C2064: term does not evaluate to a function


Yup std::binary_function<> isn't a functor.
see reference to function template instantiation '
void __cdecl std::_Unguarded_insert(
struct std::pair<int,int> *,
struct std::pair<int,int>,
struct std::binary_function<
struct std::pair<int,int>,
struct std::pair<int,int>,
bool
>

)
' being compiled


HTH.

Rob.
--
http://www.victim-prime.dsl.pipex.com/

Jul 22 '05 #5
lok
i modified the code as follow:
==================================
#include <vector>
#include <functional>
#include <string>
using std::string;

template <class T1, class T2 >
class CPairMapping {
public:
typedef std::pair<T1, T2 > ValuePair_t;
typedef std::vector<ValuePair_t > ValueList_t;

class ValuePair_IsLess {
public:
virtual bool operator() (const ValuePair_t& lhs_,const ValuePair_t&
rhs_) const;
};

void SortAscend(const ValuePair_IsLess* isLess_) {
std::sort(Map.begin(), Map.end(), *isLess_);
}
protected:
ValueList_t Map;
};

typedef CPairMapping< string, string > STR2STRMap;

class STR2STRMap_IsLess: public STR2STRMap::ValuePair_IsLess {
public:
bool operator() (const STR2STRMap::ValuePair_t& lhs_, const
STR2STRMap::ValuePair_t& rhs_) const {
return lhs_.first().size() < rhs_.first().size(); // #error line
}
};
int main() {
STR2STRMap a;
STR2STRMap_IsLess isLess;
a.SortAscend( &isLess );
return 0;
}
==================================
now vc compiler reported at #error line:
error C2064: term does not evaluate to a function
error C2228: left of '.size' must have class/struct/union type
error C2064: term does not evaluate to a function
error C2228: left of '.size' must have class/struct/union type

it seem compiler doesnt recognize STR2STRMap::ValuePair_t is a pair<
string, string > object

how can i solve this error ?
thx
Jul 22 '05 #6
lok wrote in news:69**************************@posting.google.c om:

i modified the code as follow:
==================================
Firstly my appologiess, I gave bad advise, makeing operator() virtual
was not a good idea as functors are mostly passed by value (so that
an ordinary function is also a functor), so slicing would occur
and what gets passed to std::sort is the base class with the
original operator ().

The following is a fix (of sorts) but it has no real advantage
over using a simple function pointer. Though it could if you need
to make the functor more complex.

#include <vector>
#include <functional>
#include <algorithm> // std::sort()
#include <string>

using std::string;

template <class T1, class T2 >
class CPairMapping
{
public:

typedef std::pair<T1, T2 > ValuePair_t;
typedef std::vector< ValuePair_t > ValueList_t;

class ValuePair_IsLess :
std::binary_function<
ValuePair_t const &, ValuePair_t const &, bool

{
protected:

typedef
bool (*m_cmp_t)(
ValuePair_t const &lhs_, ValuePair_t const & rhs_
)
;
m_cmp_t m_cmp;

public:

ValuePair_IsLess( m_cmp_t cmp ) : m_cmp( cmp ) {}

bool operator() (
ValuePair_t const &lhs_, ValuePair_t const &rhs_
) const
{
return m_cmp( lhs_, rhs_ );
}
};

void SortAscend( ValuePair_IsLess isLess_ )
{
std::sort( Map.begin(), Map.end(), isLess_ );
}

protected:

ValueList_t Map;
};

typedef CPairMapping< string, string > STR2STRMap;

class STR2STRMap_IsLess: public STR2STRMap::ValuePair_IsLess
{
static bool cmp(
STR2STRMap::ValuePair_t const &lhs_,
STR2STRMap::ValuePair_t const &rhs_
)
{
return lhs_.first.size() < rhs_.first.size(); // #error line

// note the lack of .first().size() ..
}

typedef STR2STRMap::ValuePair_IsLess base_t;

public:

STR2STRMap_IsLess() : base_t( cmp ) {}
};
int main()
{
STR2STRMap a;
STR2STRMap_IsLess isLess;
a.SortAscend( isLess );
return 0;
}
Here's a simple function version, there is *alot* less cruft if
you really don't need it.
#include <vector>
#include <functional>
#include <algorithm> // std::sort()
#include <string>

using std::string;

template <class T1, class T2 >
class CPairMapping
{
public:

typedef std::pair<T1, T2 > ValuePair_t;
typedef std::vector< ValuePair_t > ValueList_t;

typedef bool (*ValuePair_IsLess)(
ValuePair_t const &lhs_, ValuePair_t const & rhs_
);

void SortAscend( ValuePair_IsLess isLess_ )
{
std::sort( Map.begin(), Map.end(), isLess_ );
}

protected:

ValueList_t Map;
};

typedef CPairMapping< string, string > STR2STRMap;

bool STR2STRMap_IsLess(
STR2STRMap::ValuePair_t const &lhs_,
STR2STRMap::ValuePair_t const & rhs_
)
{
return lhs_.first.size() < rhs_.first.size();
}

int main()
{
STR2STRMap a;
//STR2STRMap_IsLess isLess;
a.SortAscend( STR2STRMap_IsLess );
return 0;
}

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #7
lok
after some little modification,
no compile, link or runtime error now
the code are follow:
=====================
#include <vector>
#include <functional>
#include <string>
using std::string;

template <class T1, class T2 >
class CPairMapping {
public:
typedef std::pair<T1, T2 > ValuePair_t;
typedef std::vector<ValuePair_t > ValueList_t;

class ValuePair_IsLess {
public:
virtual bool operator() (const ValuePair_t& lhs_,const ValuePair_t&
rhs_) const {
return lhs_ < rhs_;
}
};

void SortAscend(const ValuePair_IsLess& isLess_) {
std::sort(Map.begin(), Map.end(), isLess_);
}
protected:
ValueList_t Map;
};

typedef CPairMapping< string, string > STR2STRMap;

class STR2STRMap_IsLess: public STR2STRMap::ValuePair_IsLess {
public:
bool operator() (const STR2STRMap::ValuePair_t& lhs_, const
STR2STRMap::ValuePair_t& rhs_) const {
return lhs_.first.size() < rhs_.first.size();
}
};

int main() {
STR2STRMap a;
STR2STRMap_IsLess isLess;
a.SortAscend( &isLess );
}
=====================
but in debug mode, i found std::sort called the operator() of
CPairMapping::ValuePair_IsLess instead of the operator() of
STR2STRMap_IsLess
it seem the dynamic binding of virtual function failed to work
is this because a new CPairMapping::ValuePair_IsLess is created to
pass to the std::sort funciton ?

how to solve this problem ?

thx
Jul 22 '05 #8
lok wrote in news:69**************************@posting.google.c om:
after some little modification,
no compile, link or runtime error now
the code are follow: [snip] but in debug mode, i found std::sort called the operator() of
CPairMapping::ValuePair_IsLess instead of the operator() of
STR2STRMap_IsLess
it seem the dynamic binding of virtual function failed to work
is this because a new CPairMapping::ValuePair_IsLess is created to
pass to the std::sort funciton ?

how to solve this problem ?

This works on the 3 conpilers I tried, (unfortunatly I haven't got
VC++ 6.0). See the comments inline:

#include <vector>
#include <functional>
#include <algorithm> /* forgot this again (std::sort) */
#include <string>
#include <iostream>

using std::string;

template <class T1, class T2 >
class CPairMapping
{
public:

typedef std::pair<T1, T2 > ValuePair_t;
typedef std::vector<ValuePair_t > ValueList_t;
typedef typename std::vector<ValuePair_t >::iterator iterator;
class ValuePair_IsLess
{
public:
virtual bool operator() (
const ValuePair_t& lhs_,const ValuePair_t& rhs_
) const
{
return lhs_ < rhs_;
}
};

void SortAscend(const ValuePair_IsLess& isLess_)
{
/* This is the trick,
force std::sort to take a Comparitor by reference
*/
std::sort<
iterator, ValuePair_IsLess const &(

Map.begin(), Map.end(), isLess_
)
;
}

void add( T1 const &a, T2 const &b )
{
Map.push_back( ValuePair_t( a, b ) );
}

iterator begin() { return Map.begin(); }
iterator end() { return Map.end(); }

protected:

ValueList_t Map;
};
typedef CPairMapping< string, string > STR2STRMap;

class STR2STRMap_IsLess: public STR2STRMap::ValuePair_IsLess
{
public:
bool operator() (
const STR2STRMap::ValuePair_t& lhs_,
const STR2STRMap::ValuePair_t& rhs_
) const
{
return lhs_.first.size() < rhs_.first.size();
}
};
template < typename Iterator >
std::ostream &print_pairs( std::ostream &os, Iterator ptr, Iterator lim
)
{

if ( ptr != lim ) for (;;)
{
os << "( " << ptr->first << ", " << ptr->second << " )";
if (++ptr == lim ) break;
os << ", ";
}
return os;
}
int main()
{
STR2STRMap a;
STR2STRMap_IsLess isLess;

a.add( "2", "a" );
a.add( "1", "b" );

print_pairs( std::cerr, a.begin(), a.end() ) << "\n";

a.SortAscend( isLess ); /* pass by ref */

print_pairs( std::cerr, a.begin(), a.end() ) << "\n";
}


Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #9

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

Similar topics

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...
4
by: hall | last post by:
I accidently overloaded a static member function that I use as predicate in the std::sort() for a vector and ended up with a compiler error. Is this kind of overload not allowed for predicates and...
8
by: Manfred | last post by:
Hello I am new to template programming, so i tried the 'example' from http://www.sgi.com/tech/stl/functors.html. I can compile the code but when i want to run the program I get a segmentation...
15
by: Peter Olcott | last post by:
Does anyone know how to do this?
4
by: prakashsahni | last post by:
I am using a sort func object like struct mystruct { bool operator () (MyClass* const &a, MyClass* const&b) {}; } Invoke it like std::sort(vec.begin(), vec.end(),mystruct); Where vec is an...
5
by: fade | last post by:
Good afternoon, I need some advice on the following: I've got a class that has a member std::vector<CStringm_vFileName and a member CString m_path; The vector contains a bunch of filenames with...
11
by: Jeff Schwab | last post by:
Would std::sort ever compare an object with itself? I'm not talking about two distinct, equal-valued objects, but rather this == &that. The container being sorted is a std::vector. I've never...
1
by: Markus Dehmann | last post by:
In the following code example, I define several Comparator classes which contain different compare functions to use with std::sort. I have a Sorter class that gets passed a Comparator and is...
10
by: ikarus | last post by:
Hello C++ Gurus! I'm comparing sorting algorithm for study goals. I've compared STL std::sort and hand-coded introsort on millions (tens of millions) of integers array sorting. It was tested...
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:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
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...
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
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
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
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...

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.