Thread: Overloaded function parameter matching

  1. #1
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733

    Overloaded function parameter matching

    Hi, I'm trying to implement a mechanism which is supposed to select an appropriate overloaded function.

    1. There is a base (template if it matters) class "base_class".
    2. There are many other classes that inherit from base_class or do not.

    Now, I have a function which operates on a pointer to base_class.

    Code:
    void Foo(base_class<T>* ptr)
    {
         // do something with ptr
    }
    void Foo(void* ptr)
    {
        // do not do anything
    }
    Now let's define some classes:

    Code:
    class ClassA : public base_class<T> {
    // inherits
    };
    
    class ClassB {
    // does not inherit
    };
    
    ClassA* a;
    ClassB* b;
    For those, which inherit from base_class, a call to Foo should resolve to Foo(base_class<T>*), but for those which do not, it should resolve to Foo(void*).
    void* can be any type, since it is a dummy parameter.

    For example:
    Code:
    Foo(a);   // should call Foo(base_class<T>*)
    Foo(b);   // should call Foo(void*)
    My problem is: this code is not working as expected. For some classes compiler chooses the proper overload, but not for the others. I'm using GCC 4.4.0 (having similar results on Borland's 5.6).

    I tried many variations of templates, global functions, and structs. No RTTI, ClassB can be any type, including STL and fundamental types.

    Any ideas?
    Thanks.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Do you have a specific example of one that works opposite the way you think it should? (One that "misses" in both compilers, even?)

  3. #3
    The larch
    Join Date
    May 2006
    Posts
    3,573
    May-be a more complete example of where it doesn't work?
    I might be wrong.

    Thank you, anon. You sure know how to recognize different types of trees from quite a long way away.
    Quoted more than 1000 times (I hope).

  4. #4
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    Ok, so I have finally managed to provide a smallest non-compilable example. I've modified my library a bit and figured out that the compiler has problems with matching parameters to the first overload.

    Code:
    ////////////////////////////////////////////////////////////////////////////////
    
    #include <iostream>
    ////////////////////////////////////////////////////////////////////////////////
    template <class T>
    class HelperClass {
    };
    ////////////////////////////////////////////////////////////////////////////////
    template <class T>
    class BaseClass {
    public:
        void CallMe()
        {
            std::cout << "BaseClass::CallMe()" << std::endl;
        }
    };
    ////////////////////////////////////////////////////////////////////////////////
    template <typename T>
    void Foo(T* Ptr, HelperClass<T>* Helper, BaseClass<T>* Base)
    {
        Base->CallMe();
    }
    ////////////////////////////////////////////////////////////////////////////////
    class ClassA : public BaseClass<ClassA> {
    public:
    };
    ////////////////////////////////////////////////////////////////////////////////
    class ClassB {
    public:
    };
    ////////////////////////////////////////////////////////////////////////////////
    #ifdef __BORLANDC__
    #pragma argsused
    #endif
    int main(int argc, char* argv[])
    {
        ClassA* a;
        ClassB* b;
        HelperClass<ClassA>* helper_a;
        HelperClass<ClassB>* helper_b;
    
        std::cout << "Calling Foo(a)..." << std::endl;
        Foo<ClassA>(a, helper_a, a); // !A!
        std::cout << "Calling Foo(b)..." << std::endl;
        Foo<ClassB>(b, helper_b, b); // !B!
    
        std::system("pause");
        return 0;
    }
    ////////////////////////////////////////////////////////////////////////////////
    I'm getting the following:
    Code:
    no matching function for call to 'Foo(ClassA*&, HelperClass<ClassA>*&, ClassA*&)'
    no matching function for call to 'Foo(ClassB*&, HelperClass<ClassB>*&, ClassB*&)'
    The second message is obvious, since ClassB is not a descendant of BaseClass<ClassB>.
    But why are there any problems with the first call?

    EDIT:
    This example does not compile on both compilers, maybe I have missed some standards or there is just an obvious mistake?

    EDIT2:
    I made a stupid mistake, but it still does not work (updated code).
    Last edited by kmdv; 12-14-2010 at 08:55 AM.

  5. #5
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Error 1 error C2664: 'Foo' : cannot convert parameter 2 from 'HelperClass<T>' to 'HelperClass<T> *'
    Error 2 error C2664: 'Foo' : cannot convert parameter 2 from 'HelperClass<T>' to 'HelperClass<T> *'
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  6. #6
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    I've just noticed it, but it still does not work. Are you compiling it on MSVC?

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You're missing an overload:
    Code:
    template <typename T>
    void Foo(T* Ptr, HelperClass<T>* Helper, void* Base) {}
    And make HelperClass into a reference or take the address of your objects. It will compile.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    Thanks, it solved the example's problem and it indeed works. My real code is a bit different and there is a one-parameter member method, which also works. But still, from all of the classes which inherit from BaseClass, strangly, the compiler selects the second overload in some cases. I have to deal with it on my own.

  9. #9
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Remember that your base class is templated. The 3rd parameter must specifically inherited from BaseClass<T> where T is the type of the first argument. Otherwise the compiler will select the second overload.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  10. #10
    Registered User
    Join Date
    Aug 2010
    Location
    Poland
    Posts
    733
    After 2 days I've finally fixed it - this was happening (am not sure - probably) because the HelperClass equivalent (or maybe a different one) wasn't defined at the point of the Foo function definition. I put the Foo call into the file where every class is supposed to be fully known and now everything seems to be working.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 06-01-2009, 07:54 PM
  2. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  3. Bisection Method function value at root incorrect
    By mr_glass in forum C Programming
    Replies: 3
    Last Post: 11-10-2005, 09:10 AM
  4. c++ linking problem for x11
    By kron in forum Linux Programming
    Replies: 1
    Last Post: 11-19-2004, 10:18 AM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM