Advertisement
Help Keep Boards Alive. Support us by going ad free today. See here: https://subscriptions.boards.ie/.
If we do not hit our goal we will be forced to close the site.

Current status: https://keepboardsalive.com/

Annual subs are best for most impact. If you are still undecided on going Ad Free - you can also donate using the Paypal Donate option. All contribution helps. Thank you.
https://www.boards.ie/group/1878-subscribers-forum

Private Group for paid up members of Boards.ie. Join the club.
Hi all, please see this major site announcement: https://www.boards.ie/discussion/2058427594/boards-ie-2026

Templates and Function Pointers (C++)

  • 23-05-2006 03: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