Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

Templates and Function Pointers (C++)

Options
  • 23-05-2006 4:23pm
    #1
    Registered Users Posts: 40


    Hi,
    I am writing a template class to call a specific function on an object. Generally, the function is virtual and may be overridden, but I want to specify an override to call. (Ultimately, it'll run in a separate thread, with a message loop to handle UI updates, but I omitted that for clarity.) The code is below:
    template <class OP>
    class Operation
    {
    typedef bool (OP::*OP_FUNC)();
    
    public:
    	Operation(OP* pOp, OP_FUNC pFunc = 0) : m_pOp(pOp), m_pFunc(pFunc) { }
    	
    	bool Do()
    	{
    		if (m_pFunc)
    		{
    			// This doesn't compile
    			//return m_pOp->(OP::*(m_pFunc)());
    			
    			// This calls the "last" override
    			return (m_pOp->*(m_pFunc))();
    		}
    		else
    		{
    			// This calls the correct override
    			return m_pOp->OP::Do();
    		}
    	}
    
    protected:
    	OP* m_pOp;
    	OP_FUNC m_pFunc;
    };
    
    
    
    #include <stdio.h>
    
    class A
    {
    public:
    	A() { }
    	
    public:
    	virtual bool Do() { puts("A::Do() called."); return true; }
    	virtual bool fn() { puts("A::fn() called."); return true; }
    };
    
    class B : public A
    {
    public:
    	B() { }
    	
    public:
    	virtual bool Do() { puts("B::Do() called."); return false; }
    	virtual bool fn() { puts("B::fn() called."); return false; }
    };
    
    
    
    int main(int argc, char** argv)
    {
    	B b;
    	
    	Operation<A> do_operation(&b);
    	Operation<A> fn_operation(&b, A::fn);
    	
    	do_operation.Do();
    	fn_operation.Do();
    
    	return 0;
    }
    

    The output from this is:
    A::Do() called.
    B::fn() called.
    
    whereas I want it to be
    A::Do() called.
    A::fn() called.
    

    I don't want to have to modify A or B - in reality there are many different A's and B's in the project.

    Anyone any ideas?


Comments

  • Registered Users Posts: 40 dob99


    Consider this more serious example:
    class C : public A
    {
    public:
    	C() { }
    
    public:
    	virtual bool Do() { puts("C::Do() called."); return A::Do(); }
    	virtual bool fn()
    	{ 
    		Operation<A> fn_op(this, A::fn);
    		puts("C::fn() called.");
    		return fn_op.Do();
    	}
    };
    
    
    int main(int argc, char** argv)
    {
    	B b;
    	
    	Operation<A> do_operation(&b);
    	Operation<A> fn_operation(&b, A::fn);
    	
    	do_operation.Do();
    	fn_operation.Do();
    
    	C c;
    	c.fn();
    
    	return 0;
    }
    

    This results in an infinite loop (and actually more acurately represents what I'm trying to do).


Advertisement