Ring Buffer & templates

A

Andrea Crotti

I open a new thread since the subject changed a little.
I have my own implementation of a RingBuffer (which I guess doens't work
correctly yet, but it's
http://gist.github.com/651951

which has a template parameter.
Now supposing I want to subclass it, how do I automatically get rid of
the template parameter?

I mean I want that my subclass is a RingBuffer of a certain type, and in
plus I'm adding a few methods

--8<---------------cut here---------------start------------->8---
class CoordRingBuffer : RingBuffer
{
private:


public:
CoordRingBuffer();
Coordinate average();
Coordinate min();
};
--8<---------------cut here---------------end--------------->8---
Could I simply make this

std::vector<T> buffer;

of a certain type?
 
J

Juha Nieminen

Andrea Crotti said:
I mean I want that my subclass is a RingBuffer of a certain type, and in
plus I'm adding a few methods

--8<---------------cut here---------------start------------->8---
class CoordRingBuffer : RingBuffer

class CoordRingBuffer : public RingBuffer<YourType>
{
...
 
A

Andrea Crotti

class CoordRingBuffer : public RingBuffer<YourType>
{
...

Great thanks that's it ;)
Now the constructor looks something like
--8<---------------cut here---------------start------------->8---
CoordRingBuffer::CoordRingBuffer (size_t max_size) : RingBuffer<Coordinate>::RingBuffer(max_size)
{
}
--8<---------------cut here---------------end--------------->8---

Is that the most compact way?

And since I'm here, I don't get the ":" notation in the constructors.

I mean why don't just doing those initialization in the body of the
constructor?

What's the real difference in how they're executed??
 
L

Luc Danton

Great thanks that's it ;)
Now the constructor looks something like
--8<---------------cut here---------------start------------->8---
CoordRingBuffer::CoordRingBuffer (size_t max_size) : RingBuffer<Coordinate>::RingBuffer(max_size)
{
}
--8<---------------cut here---------------end--------------->8---

Is that the most compact way?

And since I'm here, I don't get the ":" notation in the constructors.

I mean why don't just doing those initialization in the body of the
constructor?

What's the real difference in how they're executed??

In the body of the constructor, it would not be initialization, it would
be assignment. So your member would be first value initialized, then
assigned to. This can be less than ideal. Worse, some type cannot be
assigned to at all: consider const int and references for instance. What
would you put in the constructor body then? In that way, the
initialization notation of constructors mimics the initialization syntax
of your member.

For instance, given:

class type {
type();
const int member;
};

type::type()
:
member(42)
{
// Cannot assign to member here!
}

Notice how you would initialize the member if it were separate:
const int member(42);
 
V

Victor Bazarov

Great thanks that's it ;)
Now the constructor looks something like
--8<---------------cut here---------------start------------->8---
CoordRingBuffer::CoordRingBuffer (size_t max_size) :
RingBuffer<Coordinate>::RingBuffer(max_size)
{
}
--8<---------------cut here---------------end--------------->8---

Is that the most compact way?

And since I'm here, I don't get the ":" notation in the constructors.

I mean why don't just doing those initialization in the body of the
constructor?

What's the real difference in how they're executed??

In the body of the constructor,[..]

http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.6

RTFFAQ.

V
 
A

Andrea Crotti

I tried again with the RingBuffer and some more questions.
What if I want to print out my structure, assuming that the objects
inside have the "<<" operator defined

If I put this somewhere
--8<---------------cut here---------------start------------->8---
deque<T> const_iterator it;

for (it=buffer.begin(); it!=buffer.end(); ++it) {
cout << it;
}
--8<---------------cut here---------------end--------------->8---

I thought it was correct, but maybe it's not so easy and I have to
ensure the compiler that the generic type has that function defined (or
should an exception be thrown)...
 
V

Victor Bazarov

I tried again with the RingBuffer and some more questions.
What if I want to print out my structure, assuming that the objects
inside have the "<<" operator defined

If I put this somewhere

"Somewhere"? Where?
--8<---------------cut here---------------start------------->8---
deque<T> const_iterator it;

deque said:
for (it=buffer.begin(); it!=buffer.end(); ++it) {
cout<< it;

cout << *it; // if your T type has the op<< defined for it
}
--8<---------------cut here---------------end--------------->8---

I thought it was correct, but maybe it's not so easy and I have to
ensure the compiler that the generic type has that function defined (or
should an exception be thrown)...

Not sure what you are saying. You don't need to output iterator itself,
but you do want to output the result of *dereferencing* the iterator.
That should give you your object. And there needs to be the function

::eek:perator<< ( std::eek:stream& os, const yourtype&)

defined somewhere.

V
 
A

Andrea Crotti

Juha Nieminen said:
class CoordRingBuffer : public RingBuffer<YourType>
{
...

Strange still not working

CoordRingBuffer.h:

--8<---------------cut here---------------start------------->8---
#include "Coordinate.h"
#include "RingBuffer.h"

// use std::accumulate power to sum up the values

class CoordRingBuffer : RingBuffer<Coordinate>
{
....
--8<---------------cut here---------------end--------------->8---

and Coordinate.h

--8<---------------cut here---------------start------------->8---
class Coordinate
{
public:
// TODO: add the virtual operators in overloading
Coordinate() {}
};
--8<---------------cut here---------------end--------------->8---

Trying to compile it gives

--8<---------------cut here---------------start------------->8---
CoordRingBuffer.h:6: error: ‘Coordinate’ was not declared in this scope
CoordRingBuffer.h:6: error: template argument 1 is invalid
CoordRingBuffer.h:10: error: ‘Coordinate’ does not name a type
CoordRingBuffer.h:11: error: ‘Coordinate’ does not name a type
--8<---------------cut here---------------end--------------->8---

but why I don't get it...
 
A

Andrea Crotti

Thanks to the suggestions received here now it works pretty well!

It's here below, if you see anything not nice please tell me...

I was now wondering what could be best to do to allow iteration on the
subclasses.
I could
- make "buffer" a protected variable, so in the subclass I can access directly
- just wrap the size method (as I do now) do use the normal for (int
i..) construct

Is there even a better way?
And if I got with a templated class I can't write the implementation in
another file, but why?

Before I had also a
"T pop();" function, and if I tried to make it virtual it didn't work at
all.

Maybe theoretically it's just wrong to make pop/push virtual since those
should work everywhere in the same way, right?

Thanks

--8<---------------cut here---------------start------------->8---
#ifndef RINGBUFFER_H
#define RINGBUFFER_H

#include <deque>

template<typename T>
class RingBuffer
{
// TODO: see how to make it also iterable
private:
size_t max_size;
std::deque<T> buffer;

public:
RingBuffer(size_t max_size);
void push(T el);
size_t size() { return buffer.size(); }
T operator[](int index) { return buffer[index]; }

// TODO: move in the implementation below if possible
friend ostream& operator<<(ostream& s, const RingBuffer<T>& c) {
s << c;
return s;
}
};

template<typename T>
RingBuffer<T>::RingBuffer(size_t max_size) : max_size(max_size)
{}

template<typename T>
void RingBuffer<T>::push(T el)
{
if (buffer.size() == max_size) {
buffer.pop_front();
}
buffer.push_back(el);
}

#endif /* RINGBUFFER_H */
--8<---------------cut here---------------end--------------->8---
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top