A FIR filter using Modern C++ features I'm diving into &quot;modern CPP&quot;, with wide usage of templates and containers,
So I started with FIR filter.

In signal processing, a finite impulse response (FIR) filter is a filter whose impulse response (or response to any finite length input) is of finite duration, because it settles to zero in finite time. This is in contrast to infinite impulse response (IIR) filters, which may have internal feedback and may continue to respond indefinitely (usually decaying).

So I define FIR filter as a class and apply it to single scalar value or to the vector itself
Could you please review my code in terms of C++ coding?
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;list&gt;
#include &lt;algorithm&gt;
#include &lt;complex&gt;
#include &lt;cmath&gt;
#include &lt;iomanip&gt;
#include &lt;sstream&gt;

// - Class method : operator(), constructor, various methods
// - Templates class and function
// - List and vector containers
// - Functors


template &lt;typename T&gt; std::string to_str(T &amp; arr){
  std::ostringstream os;
  os &lt;&lt; &quot;[&quot;;  for (auto x: arr){    os&lt;&lt;&quot; &quot;&lt;&lt; x &lt;&lt;&quot; &quot;;  }  os &lt;&lt; &quot;]\n&quot;; 
  return os.str();
}

template &lt;class T&gt; class FIR { 
public: 
    std::vector&lt; T &gt; coeff;  // Array of coefficents is static all the time
    std::list&lt; T &gt; taps;  // Array of is are shifting each tick
    int order;

    FIR(std::vector&lt; T &gt; v)  
    { 
       coeff = v; 
       order = coeff.size();
       taps = std::list&lt; T &gt; (coeff.size(), 0);
    } 
    void reset(){
       taps = std::list&lt; T &gt; (coeff.size(), 0);
    }
    void append( T  x){
      taps.push_front( x);
      taps.pop_back();
    }

    auto sum_product(){
      T  psum = 0;
      typename   std::list&lt; T &gt;::iterator t;
      typename std::vector&lt; T &gt;::iterator c;
      // Can we do better here?
      for (   c =coeff.begin(),     t  =taps.begin(); 
              c!=coeff.end(),       t !=taps.end();
            ++c             ,     ++t             ){
        psum += (*c) * (*t);
      }
      return psum;
    }
    
    auto operator() ( T  x){
      append(x);
       T  psum = sum_product();
      return psum;
    }

     auto operator() (std::vector&lt; T &gt; x){
     std::vector&lt; T &gt; y( x.size(), 0);
     for (int i = 0; i&lt;x.size(); ++i){
        y[i] =  operator()(x[i]);
     }
     return y;
     }
}; 
  
int main() 
{ 
    std::vector&lt;double&gt; coeff = {0.0,1.0,5.0, 1.0, 0.0};
    
    FIR&lt;double&gt; fir(coeff); 
    std::cout &lt;&lt;&quot;Coeff: &quot; &lt;&lt; to_str(fir.coeff);
    std::cout &lt;&lt;&quot;Taps : &quot;  &lt;&lt; to_str(fir.taps);
    
    
    std::cout&lt;&lt;&quot;\nTRANSFORM IN THE LOOP \n&quot;;
    std::vector&lt;double&gt; x_array = {0,1,2,3,4,5,6,0,0,0,0,0,0,13};
    for (auto x:x_array){
      auto p = fir(x);
      std::cout&lt;&lt;p&lt;&lt;&quot;  &quot;;
    }
    std::cout&lt;&lt;&quot;\n&quot;;
    fir.reset();

    std::cout&lt;&lt;&quot;\nTRANSFORM WITH FUNCTOR FOR SCALAR\n&quot;;
    std::vector&lt;double&gt; y_array( x_array.size(), 0);
    std::transform(x_array.begin(), x_array.end(), y_array.begin(), fir); 
    std::cout &lt;&lt; to_str(y_array);
    fir.reset();

    std::cout&lt;&lt;&quot;\nAPPLY FUNCTOR FOR CONTTAINER \n&quot;;
    auto y_2 = fir(x_array);
    std::cout &lt;&lt; to_str(y_2);
    fir.reset();

    return 0; 
}
class FIR has nothing private. Should it be struct?

The line
  std::list&lt; T &gt; taps;  // Array of is are shifting each tick

is somewhat contradictory. It taps a list or an array?

I don't see how order is used. Does it need to be a class member at all?

operator()(T x) is very confusing. I would argue that it shall not be an operator at all; if you really want this to be an operator, consider operator&lt;&lt;. A metaphor of shifting into a filter is much more understandable than calling a filter.

// Can we do better here? Yes.