template woes: incompatibility & inheritance issues with a function as paremeter

This is a discussion on template woes: incompatibility & inheritance issues with a function as paremeter within the C++ Programming forums, part of the General Programming Boards category; I managed to isolate a problem I'm having to this example program: Code: #include <iostream> using namespace std; //Simple inheritance ...

  1. #1
    Always learning
    Join Date
    Apr 2009
    Posts
    25

    template woes: incompatibility & inheritance issues with a function as paremeter

    I managed to isolate a problem I'm having to this example program:
    Code:
    #include <iostream>
    using namespace std;
    
    //Simple inheritance
    class Parent {};
    class Child: public Parent {};
    
    //Functions
    void foo(Parent &daddy)
    {
        cout << "Success!" << endl;
    }
    void evil(Child &object, void (*doodle)(Child &dimitri))
    {
        doodle(object);
    }
    
    int main()
    {
    
        Child object;
        foo(object); //OK
        evil(object, foo); //Compilation error
    
        return 0;
    }
    Yes, I understand the obvious error. It's expecting a function with a Child& parameter, not Parent&. But the fact is, I have another class which is a custom template container. Something like this:
    Code:
    #include <iostream>
    using namespace std;
    
    //simple inheritance
    class Parent{};
    class Child: public Parent{};
    
    //a simple template class
    template <class Type>
    class Container
    {
        public:
            void evil(Type &object, void (*doodle)(Type &item));
    };
    template <class Type>
    void Container<Type>::evil(Type &object, void (*doodle)(Type &item))
    {
        doodle(object);
    }
    
    void foo(Parent &item)
    {
        cout << "Success!" << endl;
    }
    
    int main()
    {
        Child object;//mkay
    
        foo(object); //No error
    
        Container<Child> box; //dundundun....
        Container<Parent> box2; //dundundun....
    
        box2.evil(object, foo); //No error
        box.evil(object, foo); //Compile error!!!
    
        return 0;
    }
    This second example won't work for the same reasons as the first.

    As you can see, I wish for every class derived from Parent to be able to use that function. I don't want to overload the same code over and over again. I know that it took me way more time to conjure this post than it would if I overloaded the function for every derived class, but that's not the point :P I don't want it to just "work", I want to learn efficient ways to help me when I'll be writing more complex programs in the future.

    Is there any way I can possibly do this? I'm thinking of a few abstract ways, but I'm lost.

    Thank you for your time ^^

  2. #2
    The larch
    Join Date
    May 2006
    Posts
    3,573
    How about making the template parameters independent:

    Code:
    //a simple template class
    template <class Type>
    class Container
    {
        public:
            template <class BaseType>
            void evil(Type &object, void (*doodle)(BaseType &item));
    };
    template <class Type> template <class BaseType>
    void Container<Type>::evil(Type &object, void (*doodle)(BaseType &item))
    {
        doodle(object);
    }
    Now correct usage should be allowed but attempts to pass invalid Type's to doodle should be still caught.
    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).

  3. #3
    Always learning
    Join Date
    Apr 2009
    Posts
    25
    Thank you very much, that did the trick! It makes a lot of sense too, now that I think of it.

    I applied it the idea to my actual program as well, and it's working

  4. #4
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,893
    Be more generic. Use a template parameter for the entire function parameter. Then you can pass function-like objects ("functors") and C++0x lambdas instead of normal functions if you want to.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  5. #5
    Always learning
    Join Date
    Apr 2009
    Posts
    25
    Thank you for your suggestion, I will keep that in mind. I'm still practicing and learning along the way, so "functors" and C++0x lambdas are things I've not covered yet. But, I will get to them sooner or later ^^

  6. #6
    C++まいる!Cをこわせ! Elysia's Avatar
    Join Date
    Oct 2007
    Posts
    22,455
    Think of them as objects that emulates function syntax.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  2. Deducing Function Template Arguments
    By George2 in forum C++ Programming
    Replies: 4
    Last Post: 03-12-2008, 07:29 PM
  3. template function argument deduce
    By George2 in forum C++ Programming
    Replies: 2
    Last Post: 03-11-2008, 08:56 PM
  4. Replies: 28
    Last Post: 07-16-2006, 11:35 PM
  5. Calling a Thread with a Function Pointer.
    By ScrollMaster in forum Windows Programming
    Replies: 6
    Last Post: 06-10-2006, 08:56 AM

Tags for this Thread


1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21