Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > trouble when overloading function used as predicate in std::sort

Reply
Thread Tools

trouble when overloading function used as predicate in std::sort

 
 
hall
Guest
Posts: n/a
 
      07-02-2004
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 if so, why not?
Shouldn the compiler be able to tell which of he overloaded functions to
use?

The second A::comp() is the one I accidently added and gives the error
message (in Borland C++Builder 6)

[C++ Error] Unit1.cpp E2285 Could not find a match for
'sort<_RandomAccesIter, _Compare>(A*,A*,bool(*)(const A&,const A&))'

Commenting out the line makes the code compile just fine.

//---------------------------------------------------------------------------
#include <vector>
#include <algorithm>

using namespace std;

struct A {
int a;
A(int a0): a(a0) {}
static bool comp ( const A a1, const A & a2) {return a1.a<a2.a;}
static bool comp ( const A a1 ){ return true; } //< causes
compiler error
};

int main(int argc, char* argv[])
{
vector<A> a;
a.push_back(A(4));
a.push_back(A(7));
sort( a.begin(), a.end(), A::comp );

return 0;
}
//---------------------------------------------------------------------------



--
<- remove capital x:s from e-mail to reply ->

 
Reply With Quote
 
 
 
 
Robbie Hatley
Guest
Posts: n/a
 
      07-03-2004

"hall" <(E-Mail Removed)> wrote:

> 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 if so, why not?
> Shouldn the compiler be able to tell which of he overloaded functions to
> use?
>
> The second A::comp() is the one I accidently added and gives the error
> message (in Borland C++Builder 6)
>
> [C++ Error] Unit1.cpp E2285 Could not find a match for
> 'sort<_RandomAccesIter, _Compare>(A*,A*,bool(*)(const A&,const A&))'
>
> Commenting out the line makes the code compile just fine.
>
> //---------------------------------------------------------------------------
> #include <vector>
> #include <algorithm>
>
> using namespace std;
>
> struct A {
> int a;
> A(int a0): a(a0) {}
> static bool comp ( const A a1, const A & a2) {return a1.a<a2.a;}
> static bool comp ( const A a1 ){ return true; } //< causes
> compiler error
> };
>
> int main(int argc, char* argv[])
> {
> vector<A> a;
> a.push_back(A(4));
> a.push_back(A(7));
> sort( a.begin(), a.end(), A::comp );
>
> return 0;
> }


Well, one thing that bothers me is that sort() expects the
predicate to have argument signature:

(const A&, const A&)

but you use:

(const A , const A&)

Forget the '&'?

That may not be related to your problem, but it's
an error you should look into.

I did try compiling your program on DJGPP (a port of the
Gnu C++ compiler to Windows-command-prompt environment,
from www.delorie.com ). I got this:

wd=C:\C\test
%make predicate-test
gpp -IC:/C/lib -pedantic -Wall -W -Wshadow -Wcast-qual -Wcast-align -Wconversion
-Os -s -LC:/C/lib predicate-test.cpp -lrh -lm -o C:/Software/predicate-test.exe

predicate-test.cpp: In function `int main()':
predicate-test.cpp:19: error: no matching function for call to `sort(
__gnu_cxx::__normal_iterator<A*, std::vector<A, std::allocator<A> > >,
__gnu_cxx::__normal_iterator<A*, std::vector<A, std::allocator<A> > >,
<unknown type>)'
make.exe: *** [predicate-test] Error 1

But when I comment-out the extra version of comp, it compiles fine.

I get the same results if I take the comp's out of the class and
make them global functions. I even changed the extra comp to
a totally unrelated signature:

double comp (int a, char b)
{
return a + b;
}

But any way I try it, the extra comp apparently causes
the compiler to see "comp" in your call to sort() as being
an "unknown type".

Perhaps the problem is related to the fact that the name "comp"
is a pointer to a function. Perhaps sort() can't check signatures
and relies on an unambiguous pointer-to-function called "comp",
which would preclude overloading.


--
Cheers,
Robbie Hatley
Tustin, CA, USA
email: lonewolfintj at pacbell dot net
web: home dot pacbell dot net slant earnur slant






----== Posted via Newsfeed.Com - Unlimited-Uncensored-Secure Usenet News==----
http://www.newsfeed.com The #1 Newsgroup Service in the World! >100,000 Newsgroups
---= 19 East/West-Coast Specialized Servers - Total Privacy via Encryption =---
 
Reply With Quote
 
 
 
 
hall
Guest
Posts: n/a
 
      07-03-2004


Robbie Hatley wrote:

> "hall" <(E-Mail Removed)> wrote:
>
>
>>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 if so, why not?
>>Shouldn the compiler be able to tell which of he overloaded functions to
>>use?
>>
>>The second A::comp() is the one I accidently added and gives the error
>>message (in Borland C++Builder 6)
>>
>>[C++ Error] Unit1.cpp E2285 Could not find a match for
>>'sort<_RandomAccesIter, _Compare>(A*,A*,bool(*)(const A&,const A&))'
>>
>>Commenting out the line makes the code compile just fine.
>>
>>//---------------------------------------------------------------------------
>>#include <vector>
>>#include <algorithm>
>>
>>using namespace std;
>>
>>struct A {
>> int a;
>> A(int a0): a(a0) {}
>> static bool comp ( const A a1, const A & a2) {return a1.a<a2.a;}
>> static bool comp ( const A a1 ){ return true; } //< causes
>>compiler error
>>};
>>
>>int main(int argc, char* argv[])
>>{
>> vector<A> a;
>> a.push_back(A(4));
>> a.push_back(A(7));
>> sort( a.begin(), a.end(), A::comp );
>>
>> return 0;
>>}

>
>
> Well, one thing that bothers me is that sort() expects the
> predicate to have argument signature:
>
> (const A&, const A&)
>
> but you use:
>
> (const A , const A&)
>
> Forget the '&'?


Ah, yes, the & apperantly got lost when I wrote the example. However it
was (const A& , const A&) in the piece of code where the problem first
occured.

>
> That may not be related to your problem, but it's
> an error you should look into.
>
> I did try compiling your program on DJGPP (a port of the
> Gnu C++ compiler to Windows-command-prompt environment,
> from www.delorie.com ). I got this:
>
> wd=C:\C\test
> %make predicate-test
> gpp -IC:/C/lib -pedantic -Wall -W -Wshadow -Wcast-qual -Wcast-align -Wconversion
> -Os -s -LC:/C/lib predicate-test.cpp -lrh -lm -o C:/Software/predicate-test.exe
>
> predicate-test.cpp: In function `int main()':
> predicate-test.cpp:19: error: no matching function for call to `sort(
> __gnu_cxx::__normal_iterator<A*, std::vector<A, std::allocator<A> > >,
> __gnu_cxx::__normal_iterator<A*, std::vector<A, std::allocator<A> > >,
> <unknown type>)'
> make.exe: *** [predicate-test] Error 1
>
> But when I comment-out the extra version of comp, it compiles fine.
>
> I get the same results if I take the comp's out of the class and
> make them global functions. I even changed the extra comp to
> a totally unrelated signature:
>
> double comp (int a, char b)
> {
> return a + b;
> }
>
> But any way I try it, the extra comp apparently causes
> the compiler to see "comp" in your call to sort() as being
> an "unknown type".
>
> Perhaps the problem is related to the fact that the name "comp"
> is a pointer to a function. Perhaps sort() can't check signatures
> and relies on an unambiguous pointer-to-function called "comp",
> which would preclude overloading.
>
>


Yes, so it seems. I am interested to find out more precisly why the
compiler cannot tell which version of comp to use. As the compiler error
messages in this case didn't help much (at least not me), it would be
good to know if this problem may occur somwhere else.

I made a small test for the pointer theory:

//------------------------------------------------------------------------
#include <string>
#include <iostream>
using namespace std;

void fun (int &i){ cout << "fun(int&): "<<i; }
void fun (string s) {cout << "fun(string&): "<<s;}
foo( void (*f)(int&)){ f(1); }

int main(int argc, char* argv[])
{
foo(fun);
return 0;
}
//---------------------------------------------------------------------------


This will compile and correctly run fun(int&), so here the compiler
seems to know which of the overloaded fun() to use. Now, pointers to
functions aren't someting i'm good at, so this may not be an equivalent
case to the original problem with std::sort(). But then what is the
difference? The fact that sort is templatized?

Any comments are appreachiated.

regards
hall

--
<- remove capital x:s from e-mail to reply ->

 
Reply With Quote
 
John Harrison
Guest
Posts: n/a
 
      07-03-2004
>
> Yes, so it seems. I am interested to find out more precisly why the
> compiler cannot tell which version of comp to use. As the compiler error
> messages in this case didn't help much (at least not me), it would be
> good to know if this problem may occur somwhere else.
>


You are confusing two different processes. The first process is template
argument deduction. std::sort has a definition something like this

template <class I, class F>
void sort(I first, I last, F comp)
{
...
}

and when you call std::sort the compiler attempt to match the types you
supply with the types in the template. Now here's the rub, sort is defined
with a third parameter F, *anything* will match this parameter, literally
anything, int, string, bool, you name it. Obviously in this situation the
compiler cannot decide between your two versions of comp because they both
match. It is only later that the compiler says, well now I know what F is,
does it make sense with the actual code of std::sort.

It would be a different story if sort was defined like this

template <class I, class T>
void sort(I first, I last, bool (*comp)(T, T))
{
...
}

because then obviously only the two argument version of your comp function
could match. However std::sort isn't defined like that probably because it
would mean std::sort could only be used with function pointers and not
functors.

john
 
Reply With Quote
 
hall
Guest
Posts: n/a
 
      07-03-2004


John Harrison wrote:

[snip]

>
> It would be a different story if sort was defined like this
>
> template <class I, class T>
> void sort(I first, I last, bool (*comp)(T, T))
> {
> ...
> }
>


This is how i thought that sort was defined and thus my confusion, but
as you explain below, this definition would not be a good idea.

> because then obviously only the two argument version of your comp
> function could match. However std::sort isn't defined like that
> probably because it would mean std::sort could only be used with
> function pointers and not functors.
>
> john


Thanks!
hall


--
<- remove capital x:s from e-mail to reply ->

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Trouble using class method as sort predicate scholtes C++ 0 08-04-2008 07:06 PM
The Hack of bitmask used as Predicate Parameters Xah Lee Perl Misc 0 04-23-2007 10:53 AM
The Hack of bitmask used as Predicate Parameters Xah Lee Java 0 04-23-2007 10:53 AM
Overloading __init__ & Function overloading Iyer, Prasad C Python 3 09-30-2005 02:17 PM
Re: Overloading __init__ & Function overloading Fredrik Lundh Python 0 09-30-2005 01:53 PM



Advertisments