Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C++ (http://www.velocityreviews.com/forums/f39-c.html)
-   -   trouble when overloading function used as predicate in std::sort (http://www.velocityreviews.com/forums/t284155-trouble-when-overloading-function-used-as-predicate-in-std-sort.html)

hall 07-02-2004 10:50 PM

trouble when overloading function used as predicate in std::sort
 
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 ->


Robbie Hatley 07-03-2004 05:06 AM

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

"hall" <Xcrackhead_eX@yahoo.se> 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 =---

hall 07-03-2004 11:09 AM

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


Robbie Hatley wrote:

> "hall" <Xcrackhead_eX@yahoo.se> 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 ->


John Harrison 07-03-2004 12:02 PM

Re: trouble when overloading function used as predicate in std::sort
 
>
> 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

hall 07-03-2004 12:13 PM

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


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 ->



All times are GMT. The time now is 08:17 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.