Thread: C++ Templated Linked List

  1. #1
    Registered User
    Join Date
    Oct 2005
    Location
    Brasil
    Posts
    220

    C++ Templated Linked List

    Hi, i´m doing a image/video processing library and i wanted to do a cascade style acquisition, processing and displaying. More or less like the following:
    Code:
    VideoNode<VideoSource> source("/dev/video0");
    
    source.connect(VideoNode<BlurEffect>);
    source.connect(VideoNode<OutputToWindow>);
    source.connect(VideoNode<EdgeDetector>);
    source.connect(VideoNode<OutputToFile>);
    And i wanted to use templates instead of abstract classes to don&#180;t suffer it&#180;s overheads (virtual function call). So i
    came up with the following code:

    Code:
    template<class T>
    class VideoObject
    {
    public:
    	VideoObject() : object()
    	{
    		this->child  = NULL;
    	};
    
    	void connect(VideoObject& child)
    	{
    		this->child = child;
    	}
    private:
    	T object;
    	VideoObject child;
    
    	void nextFrame(unsigned char** buffer)
    	{
    		object->nextFrame(buffer);
    
    		if (child != NULL)
    		{
    			child->nextFrame(buffer);
    		}
    	}
    };
    But it seems that something is pretty wrong... The compiler gave me the following output:
    Code:
    1>c:\felipe\scarvideo\scarvideo\VideoObject.h(29) : error C2460: 'VideoObject<T>::child' : uses 'VideoObject<T>', 
    which is being defined
    1>        with
    1>        [
    1>            T=Source
    1>        ]
    1>        .\main.cpp(40) : see reference to class template instantiation 'VideoObject<T>' being compiled
    1>        with
    1>        [
    1>            T=Source
    1>        ]
    1>c:\felipe\scarvideo\scarvideo\VideoObject.h(29) : error C2460: 'VideoObject<T>::child' : uses 'VideoObject<T>', 
    which is being defined
    1>        with
    1>        [
    1>            T=Etc
    1>        ]
    1>        .\main.cpp(41) : see reference to class template instantiation 'VideoObject<T>' being compiled
    1>        with
    1>        [
    1>            T=Etc
    1>        ]
    1>.\main.cpp(43) : error C2664: 'VideoObject<T>::connect' : cannot convert parameter 1 from 'VideoObject<T>' to 'VideoObject<T> &'
    1>        with
    1>        [
    1>            T=Source
    1>        ]
    1>        and
    1>        [
    1>            T=Etc
    1>        ]
    1>        and
    1>        [
    1>            T=Source
    1>        ]
    And this is the test code:

    Code:
    #include "VideoObject.h"
    #include <iostream>
    
    using namespace std;
    
    class Source
    {
    public:
    	Source() 
    	{ 
    		this->name = "source"; 
    	}
    	void nextFrame(unsigned char** buffer)
    	{
    		*buffer = new unsigned char[3];
    		strcpy((char*)*buffer, "ls");
    	}
    private:
    	string name;
    };
    
    class Etc
    {
    public:
    	Etc()
    	{
    		name = "etc";
    	}
    	void nextFrame(unsigned char** buffer)
    	{
    		cout << "name: "<<name.c_str()<<"\nbuffer: "<<buffer<<"\n";
    	}
    
    private:
    	string name;
    };
    
    int main()
    {
    	VideoObject<Source> parent;
    	VideoObject<Etc>    child;
    	
    	parent.connect(child);
    }
    What could i do?

    Ah, and yes, all filters, outputs and sources implement the nextFrame function in order to work with the VideoObject class.

    Felipe.
    Last edited by Scarvenger; 10-07-2007 at 04:30 PM.

  2. #2
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    >> VideoObject child;
    That has to be a pointer:

    VideoObject *child;

    If you think about what you're trying to do it doesn't really make sense. You're going to have to dynamically allocate and then delete your child variable when needed.

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You can only do the whole "use templates to build the processing chain thing and avoid virtual calls" thing at compile time, i.e. at construction of the processing chain. By the time you call connect() it's too late.

    I'm currently doing something similar with very basic I/O components, and the code is very involved. Also, the resulting types are not pretty. Even a simple chain could have a type like:
    Code:
    fixed_read_ahead_buffer_filter< gzip_compressor_filter< file_source >, 1024 >
    And that's just from building this chain:
    Code:
    read_file(filename) | gzip() | buffer<1024>()
    On the plus side, it has zero overhead.

    So yes, it's possible, but it takes a lot of experience with templates and template metaprogramming.
    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

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Following CTools
    By EstateMatt in forum C Programming
    Replies: 5
    Last Post: 06-26-2008, 10:10 AM
  2. Replies: 5
    Last Post: 11-04-2006, 06:39 PM
  3. Reverse function for linked list
    By Brigs76 in forum C++ Programming
    Replies: 1
    Last Post: 10-25-2006, 10:01 AM
  4. Template Class for Linked List
    By pecymanski in forum C++ Programming
    Replies: 2
    Last Post: 12-04-2001, 09:07 PM
  5. singly linked list
    By clarinetster in forum C Programming
    Replies: 2
    Last Post: 08-26-2001, 10:21 PM