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

Discussion in 'C++' started by hall, Jul 2, 2004.

  1. hall

    hall Guest

    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 ->
    hall, Jul 2, 2004
    #1
    1. Advertising

  2. "hall" <> 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 =---
    Robbie Hatley, Jul 3, 2004
    #2
    1. Advertising

  3. hall

    hall Guest

    Robbie Hatley wrote:

    > "hall" <> 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 ->
    hall, Jul 3, 2004
    #3
  4. >
    > 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
    John Harrison, Jul 3, 2004
    #4
  5. hall

    hall Guest

    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 ->
    hall, Jul 3, 2004
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    1
    Views:
    471
    Marcus Kwok
    Apr 6, 2007
  2. Replies:
    4
    Views:
    458
  3. scholtes

    Trouble using class method as sort predicate

    scholtes, Aug 4, 2008, in forum: C Programming
    Replies:
    0
    Views:
    432
    scholtes
    Aug 4, 2008
  4. Ganesh
    Replies:
    3
    Views:
    339
    James Kanze
    Sep 30, 2008
  5. Victor Bazarov
    Replies:
    3
    Views:
    808
    James Kanze
    Feb 2, 2010
Loading...

Share This Page