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
Hi there,
There is an issue with role permissions that is being worked on at the moment.
If you are having trouble with access or permissions on regional forums please post here to get access: https://www.boards.ie/discussion/2058365403/you-do-not-have-permission-for-that#latest

Templates and Function Pointers (C++)

  • 23-05-2006 3:23pm
    #1
    Registered Users, Registered Users 2 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, Registered Users 2 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