I'm currently toying around with some Computer Vision algorithms and always wanted to learn more about templates, so I came up with the idea to build a templated Image Processing Pipeline.I want the pipeline to be built of several task blocks which I want to plug into each other sequentially. For a specific block, its input and output types are fixed. I ultimately want to be able to inherently control for a block to only accept the next block if the output type of the current is identical to the input type of the next.         Block_N                 Block_N+1     _______________         _________________ int |               |  str  |                 | float--->| str = f1(int) |------>| float = f2(str) |------->    |_______________|       |_________________|Consequently, Block_N+2 would have to accept float as input and may have an arbitrary output type. This is what I was able to come up with:Abstract base classes:template<class I>class AbstractInput {public:    virtual ~AbstractInput() { }    virtual void call( I _input ) = 0;};template<class I, class O>class AbstractPipelineTask : public AbstractInput<I> {public:    typedef AbstractInput<O>* Ptr;    AbstractPipelineTask( AbstractInput<O>* _nextTask = NULL)         : m_nextTask ( _nextTask ) { }    virtual void call( I _input ) {        m_input = _input;        m_output = executeTask( m_input );        if ( m_nextTask )            m_nextTask->call( m_output );    }    virtual O executeTask( I& _input ) = 0;protected:      AbstractInput<O>* m_nextTask;    I m_input;    O m_output;};Example implementation:class Str2IntPipelineTask : public AbstractPipelineTask< std::string, int > {public:    Str2IntPipelineTask( AbstractInput<int>* _nextTask = NULL )         : AbstractPipelineTask( _nextTask ) { }    virtual ~Str2IntPipelineTask() { }    virtual int executeTask( std::string& _input ) {        return atoi( _input.c_str() );    }};class Int2IntPipelineTask : public AbstractPipelineTask< int, int> {public:    Int2IntPipelineTask( AbstractInput<int>* _nextTask = NULL )         : AbstractPipelineTask( _nextTask ) { }    virtual ~Int2IntPipelineTask() { }    virtual int executeTask( int& _input ) {        return ( _input * _input );    }};class Int2FloatPipelineTask : public AbstractPipelineTask< int, float > {public:    Int2FloatPipelineTask( AbstractInput<float>* _nextTask = NULL )         : AbstractPipelineTask( _nextTask ) { }    virtual ~Int2FloatPipelineTask() { }    virtual float executeTask( int& _input ) {        return ( static_cast<float>( _input ) / 42.f );    }};Examples:int _tmain(int argc, _TCHAR* argv[]){    Int2FloatPipelineTask* pipeTask2    = new Int2FloatPipelineTask( );    Int2IntPipelineTask* pipeTask1      = new Int2IntPipelineTask( pipeTask2 );    Str2IntPipelineTask* pipeTask0      = new Str2IntPipelineTask( pipeTask1 );    pipeTask0->call( 42 );    return 0;}What I would really like to know besides some general advice is:How can I get rid of the raw pointers AbstractInput<O>* m_nextTask? I tried changing the typedef of Ptr to std::shared_ptr<AbstractInput<O>> but that broke the derived classes constructors.Is it possible to get rid of AbstractInput?
Image Processing Pipeline
c++;template;polymorphism