5

I'm writing a FIR filter that is supposed to calculate running average of an input sequence.

class RunningAverager
{
    public:
        RunningAverager(uint64_t FilterOrder)
        {
            for (uint64_t i=0; i<FilterOrder; i++)
            {
                Registers.push(0);
            }
        }
        uint64_t GetAverage(uint64_t NewInput)
        {
            Registers.push(NewInput);
            Registers.pop();
            return GetAverage();
        }
        uint64_t GetAverage() const
        {
            uint64_t Sum = 0;
            //for (uint64_t i=0; i<Registers.size(); i++)       <-- Works
            for (std::stack<uint64_t>::const_reference ref=Registers.begin(); ref!=Registers.end(); ???)
            {   // begin() and end() methods do not exist for std::stack
                //Sum += Registers[i];      Doesn't work, because the [] operator is not overloaded.
                Sum += ref;
            }
            return Sum / Registers.size();
        }
    private:
        std::stack<uint64_t> Registers;
};

I am having trouble iterating the std::stack object Registers. Unlike other STL containers, it doesn't give an iterator or random access operator.

How do I loop and std::stack object?

An example usage:

RunningAverager ra(10);

while(...)
{
    FilteredSpeed = ra.GetAverage(ActualSpeed);
}
hkBattousai
  • 10,583
  • 18
  • 76
  • 124
  • 4
    You can't iterate over a stack. That's the whole point of a stack. – Kerrek SB Aug 08 '13 at 11:53
  • I think you should use something like `boost::circular_buffer` instead of `std::stack` for the reason @KerrekSB mentioned. – arne Aug 08 '13 at 11:54

3 Answers3

1

You push the values on the stack in the first loop. So you can pop them off in the second loop and add them up and count them to get the average.

David Elliman
  • 1,379
  • 8
  • 15
1

You could use a std::deque in place of a stack, using push_front and pop_front.

dunc123
  • 2,595
  • 1
  • 11
  • 11
1

It is easier to use std::deque container for this particular application.

class RunningAverage
{
    public:
        RunningAverage(uint64_t Order)
        {
            for (uint64_t i=0; i<Order; i++)
            {
                Registers.resize(Order, 0);
            }
        }
        uint64_t GetAverage(uint64_t NewInput)
        {
            Registers.push_back(NewInput);
            Registers.pop_front();
            return GetAverage();
        }
        uint64_t GetAverage() const
        {
            uint64_t Sum = 0;
            for (std::deque<uint64_t>::const_iterator it=Registers.begin(); it<Registers.end(); ++it)
            {
                Sum += *it;
            }
            return Sum / Registers.size();
        }
    private:
        std::deque<uint64_t> Registers;
};
hkBattousai
  • 10,583
  • 18
  • 76
  • 124