Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I iterate `std::stack` elements in a for loop? [duplicate]

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);
}
like image 892
hkBattousai Avatar asked Nov 03 '22 17:11

hkBattousai


2 Answers

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

like image 82
dunc123 Avatar answered Nov 15 '22 05:11

dunc123


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;
};
like image 26
hkBattousai Avatar answered Nov 15 '22 05:11

hkBattousai