2013-08-08 18 views
5

Sto scrivendo un filtro FIR che dovrebbe calcolare running average di una sequenza di input.Come faccio a ripetere gli elementi `std :: stack` in un ciclo for?

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; 
}; 

Sto avendo difficoltà iterazione l'std::stack oggetto Registers. A differenza di altri contenitori STL, non fornisce un iteratore o un operatore di accesso casuale.

Come si esegue il loop e l'oggetto std::stack?

Un esempio d'uso:

RunningAverager ra(10); 

while(...) 
{ 
    FilteredSpeed = ra.GetAverage(ActualSpeed); 
} 
+3

Non è possibile eseguire iterazioni su una pila. Questo è l'intero punto di una pila. –

+0

Penso che dovresti usare qualcosa come "boost :: circular_buffer' invece di' std :: stack' per la ragione menzionata da @KerrekSB. – arne

risposta

0

È spingere i valori sullo stack nel primo ciclo. Quindi puoi saltarli fuori nel secondo ciclo e aggiungerli e contarli per ottenere la media.

1

È possibile utilizzare uno std::deque al posto di uno stack, utilizzando push_front e pop_front.

1

È più facile utilizzare il contenitore std::deque per questa particolare applicazione.

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; 
};