Verwendung template klasse als attribut



  • Guten Morgen!!

    Ich verzweifel gerade an der Verwendung eines templates. Ich habe eine ringbuffer class mit folgender definition

    template <typename kind, int RING_BUFFER_SIZE> class ringbuffer{...}
    

    allerdings schaffe ich es nicht, in einer anderen klasse als attribut zu deklarieren...

    rinbuffer<char, 5> myBuffer
    

    sagt immer:

    Fehler: expexted >>:<< before >><> token
    Fehler: ISO-C++ verbietet Deklaration von >>ringbuffer<< ohne Typ
    

    Ich verwende Linux und den GCC... hat irgend jemand eine Idee?

    vielen Dank im voraus!
    Peter



  • Ich denke mal, dass du rinbuffer falsch geschrieben hast, sollte das nicht eher ringbuffer heissen?



  • habs scho im sourcecode richtig geschrieben, allerdings hier im post falsch 🙂



  • OK.
    Dann zeig mal bitte, was du wirklich hast. ( Warum meiden hier alle copy-paste?!)
    Wie aktuell ist dein Compiler? - Manche ältere haben Probleme mit Templates..


  • Administrator

    drakon schrieb:

    ( Warum meiden hier alle copy-paste?!)

    Wohl aus zwei Gründen:
    1. Wir könnten ihren Code klauen, der doch immer ach so gut ist 🙂
    2. Gewisse sind so klug und wollen uns nicht mit all zu viel Code erschlagen. Das ist ja eigentlich eine gute Idee, aber viele kürzen am Ende dann doch zu viel weg.

    @escapete,
    Ein gekürzter Header von ringbuffer und die Zeile oder auch ein paar mehr (oben und unten), von der Stelle wo der Fehler auftaucht.

    Oder einen kurzen ähnlichen Code, wo der gleiche Fehler auftritt. Beim erstellen dieses kurzen Codes erkennt man den Fehler manchmal selbst 😉

    Grüssli



  • Verwende den GCC in Version 4.2.3 (Thread-Modell: Posix)

    hier meine ringbuffer class, die ich in einer anderen classe als attribut verwenden will...

    template <class kind, int RING_BUFFER_SIZE>class ringbuffer {
    private:
        kind buffer[RING_BUFFER_SIZE];
        int readPointer;
        int writePointer;
        int usedSpace;
        int availSpace;
    
    public:
    	ringbuffer(){
        	#ifdef DEBUG_RING_BUFFER
        		cout << "Template RingBuffer Constructor" << endl;
        	#endif 
        	readPointer = 0;
        	writePointer = 0;
        	availSpace = RING_BUFFER_SIZE;
        	usedSpace = 0;
        }
        ~ringbuffer(){
        	#ifdef DEBUG_RING_BUFFER
        		cout << "Template RingBuffer Destructor" << endl;
        	#endif    
        	delete []buffer;
        }
    
    	ringbuffer(ringbuffer & old_ring_buf) {
    		#ifdef DEBUG_RING_BUFFER
    			cout << "Template RingBuffer Constructor Overloaded" << endl;
    		#endif
    	        this->memcpy(this->buffer, old_ring_buf.buffer, RING_BUFFER_SIZE*sizeof(kind));
    	        readPointer = old_ring_buf.readPointer;
    	        writePointer = old_ring_buf.writePointer;
    	        usedSpace =  old_ring_buf.usedSpace;
    	        availSpace = old_ring_buf.availSpace;
    	}
    
    	int append(kind * data, int length){
    
    		#ifdef DEBUG_RING_BUFFER
    			cout << "Template RingBuffer Append-extended" << endl;
    		#endif
    
    		// enough space in buffer?
    		if(length <= availSpace ){
    			if(writePointer >= RING_BUFFER_SIZE) {
    				writePointer = 0;
    	    	}
    
    			#ifdef DEBUG_RING_BUFFER
    				cout << " Information - ";
    				cout << "readPtr: "<< readPointer;
    				cout << ", writePtr: "<< writePointer;
    				cout << ", used: " << usedSpace; 
    				cout << ", available: "<< availSpace;
    				cout << ", length: " << length;
    				cout << ", Offset: " <<  (sizeof(kind)*writePointer) << endl;
    			#endif
    
    			// proof if a wrap around is necessary
    			if(length <= RING_BUFFER_SIZE-writePointer){
    				#ifdef DEBUG_RING_BUFFER
    					cout << "NO WRAP AROUND"<<endl;
    				#endif
    				// no wrap around - copy all data
    				memcpy(buffer + (writePointer), data, sizeof(kind)*length);
    
    				writePointer += length;
    				usedSpace += length;
    				availSpace -= length;
    
    			}else{
    				// wrap around
    				int dumReadPointer = readPointer;
    				#ifdef DEBUG_RING_BUFFER
    					cout << "WRAP AROUND"<<endl;
    				#endif
    				// Bug?! readPointer is set to 0 after memcpy - dont know why
    				memcpy(buffer + (writePointer), data, sizeof(RING_BUFFER_SIZE-writePointer));
    				memcpy(buffer, data + (RING_BUFFER_SIZE-writePointer), sizeof(kind)*(length-(RING_BUFFER_SIZE-writePointer)));
    
    				availSpace -= length;
    				usedSpace+= length;
    				int dummy; 
    				//dummy = length-sizeof(kind)*(RING_BUFFER_SIZE-writePointer);
    				dummy = length-(RING_BUFFER_SIZE-writePointer);
    				writePointer = length-(RING_BUFFER_SIZE-writePointer); //dummy;
    				readPointer = dumReadPointer;
    			}
    
    			#ifdef DEBUG_RING_BUFFER
    				cout << "_Information - ";
    				cout << "readPtr: "<< readPointer;
    				cout << ", writePtr: "<< writePointer;
    				cout << ", used: " << usedSpace; 
    				cout << ", available: "<< availSpace;
    				cout << ", length: " << length;
    				cout << ", Offset: " <<  (sizeof(kind)*writePointer) << endl;
    			#endif
    			return 0;	
    
    		}
    		else {
    			#ifdef DEBUG_RING_BUFFER
    				cout << "Not enough space in buffer to copy data"<< endl;
    			#endif
    		}
    		return -1;
    	}
    
    	int append(kind value) {
    		#ifdef DEBUG_RING_BUFFER
    			cout << "Template RingBuffer Append" << endl;
    		#endif
    		if(availSpace <= 0 && usedSpace >= RING_BUFFER_SIZE){
    			#ifdef DEBUG_RING_BUFFER
    				cout << "Not enough space in buffer to copy value"<< endl;
    			#endif
    			return -1;
    		}
    
    	    if(writePointer >= RING_BUFFER_SIZE) {
    	        writePointer = 0;
    	    }
    
    		#ifdef DEBUG_RING_BUFFER
    			cout << "Information - ";
    			cout << "readPtr: "<< readPointer;
    			cout << ", writePtr: "<< writePointer;
    			cout << ", used: " << usedSpace; 
    			cout << ", available: "<< availSpace;
    			cout << ", Offset: " <<  (sizeof(kind)*writePointer) << endl;
    		#endif
    
    	    *( buffer + writePointer  )= value;
    		availSpace--;
    		usedSpace++;
    	    ++writePointer;
    
    		#ifdef DEBUG_RING_BUFFER
    			cout << "_Information - ";
    			cout << "readPtr: "<< readPointer;
    			cout << ", writePtr: "<< writePointer;
    			cout << ", used: " << usedSpace; 
    			cout << ", available: "<< availSpace;
    			cout << ", Offset: " <<  (sizeof(kind)*writePointer) << endl;
    		#endif
    	    return 0;
    	}
    
        kind get(){   
    		#ifdef DEBUG_RING_BUFFER
    			cout << "Template RingBuffer Get" << endl;
    		#endif
    
        	if(usedSpace <= 0 && availSpace >= RING_BUFFER_SIZE){
        		#ifdef DEBUG_RING_BUFFER
        			cout << "Buffer empty - Can't return any value" << endl;
        		#endif    		
        		return NULL;
        	}
    
        	if(readPointer >= RING_BUFFER_SIZE) {
                readPointer = 0;
            }
    		usedSpace--;
    		availSpace++;
    
            ++readPointer;
    
    	return(buffer[(readPointer-1)]);
        }
    
        kind get(kind * data, int length){
        	// it is not possible to require more data than available
    		if(length > usedSpace)
        		return NULL;
    
        	// proof, if the buffer is empty
        	if(usedSpace <= 0 && availSpace >= RING_BUFFER_SIZE){
        		cout << "Buffer empty " << endl;
        		return NULL;
        	}
        	// t.b.d. not in the mood
        	// tbd
    
    		if(readPointer >= RING_BUFFER_SIZE) {
    		        readPointer = 0;
            }
    
    		usedSpace--;
    		availSpace++;
    
    	    ++readPointer;
            //return( buffer[(readPointer-1)] );
        }
    
        int readPos(){
            return (readPointer);
        }
    
        int writePos(){
            return (writePointer);
        }
        int available(){
            return (availSpace);
        }
        int used(){
            return (usedSpace);
        }
    
    }; 
    
    #endif /*RINGBUFFER_H_*/
    

    hier die class, die den ringbuffer verwenden soll...

    class test{
    
    	private:
    
    	    int fileDescriptor;
    	    char portName[PORT_NAME_LENGTH];
        	    bool mIsOpen;
    
        	    ringbuffer<char, 5>p;
                // etc...
    


  • fehler gefunden... hatte n doofes include am anfang der datei (include der test.h) in der ringbuffer.h...



  • ~ringbuffer(){
            #ifdef DEBUG_RING_BUFFER
                cout << "Template RingBuffer Destructor" << endl;
            #endif    
            delete []buffer;
        }
    

    Ob das delete[] so eine gute Idee ist...

    Ebenso das hier:

    memcpy(buffer + (writePointer), data, sizeof(kind)*length);
    

    Was passiert, wenn kind ein Typ ist, der selbst Objekte auf dem Heap via Konstruktor anlegt?



  • merke: benutze NIE memcpy bei Typen die keine PODs sind. Also auch nicht bei Template-Parametern die non-POD Klassen sein können. Für solche Zwecke kann man in C++ eigentlich immer (auch für PODs) std::copy benutzen.


Anmelden zum Antworten