title: Expression template : unroll loop
body: <p>I have the same kind of questions that:
  <a href="https://stackoverflow.com/questions/15856122/expression-templates-improving-performance-in-evaluating-expressions">Expression templates: improving performance in evaluating expressions?</a></p>
  
  <p>My aim is to unroll loop of this expression</p>
  
  <pre><code>auto &amp;&amp; intermediate = A+D*C
  for(int i= 0; i&lt;10 ;i++)
      intermediate = intermediate + B
  Vector result = intermediate * E
  </code></pre>
  
  <p>I would like to have in intermediate the whole tree of binary expression and that finally operator=(Expression ) of the class Vector run the inspection of the graph
  With my code it works only without the loop for ( I use the classical implementation of expression template , the one of Joel Falcou @cppcon 2015)</p>
  
  <p>Edit : code compile issue due to the loop</p>
  
  <p>if I uncomment the loop into the main I have the compiled error
  need to run with c++11</p>
  
  <p>g++ -std=c++11 -O3 -fopenmp -Wall -pedantic -pthread main.cpp &amp;&amp; ./a.out</p>
  
  <pre><code>#include &lt;vector&gt;
  #include &lt;iostream&gt;
  
  template &lt;typename TBase, typename Derived&gt;
  struct BaseExpression
  {
     Derived const&amp; self() const { return static_cast&lt;const Derived&amp;&gt;(*this); }
     Derived &amp; self() { return static_cast&lt;Derived&amp;&gt;(*this); }
     TBase operator[](size_t szIdx) const { return self()[szIdx]; }
     size_t size() const {return self().size();}
  };
  
  template &lt;typename TBase, typename Operator, typename OP1, typename OP2&gt;
  class Binary_Expression : public BaseExpression&lt;TBase, Binary_Expression&lt;TBase, Operator, OP1, OP2&gt; &gt;
  {
  public:
     Binary_Expression(OP1 const &amp; a, OP2 const &amp; b) : op1(a), op2(b){}
     TBase operator[] (size_t idx) const { return op(op1[idx], op2[idx]); }
     size_t size() const { return op1.size() != 0 ? op1.size() : op2.size(); }
  
  
  private:
     const OP1 &amp; op1;
     const OP2 &amp; op2;
     Operator op;
  };
  
  
  template &lt;typename TBase &gt;
  class Vector : public BaseExpression&lt;TBase, Vector&lt;TBase&gt; &gt;
  {
  
  public:
     explicit Vector(size_t szSizeN) : m_xMemory(szSizeN){}
  
     Vector(const Vector &amp;orig): m_xMemory()
     { 
        this-&gt;copy(orig);
     }
  
     Vector &amp; operator=(const Vector &amp;orig)
     {
        if (&amp;orig != this)
        {
           Vector temp(orig);
           this-&gt;swap(temp);
        }
  
        return *this;
     }
  
     Vector &amp; operator=(TBase factor)
     {
        size_t szSizeN = size();
  #pragma omp parallel for
        for (size_t idx = 0; idx &lt; szSizeN; idx++)
        {
           m_xMemory[idx] = factor;
        }
  
        return *this;
     }
  
     template &lt;typename Expression&gt;
     Vector(const BaseExpression&lt;TBase, Expression&gt; &amp;b) :m_xMemory(b.size())
     {
        size_t szSizeN = size();
  #pragma omp parallel for
        for (size_t idx = 0; idx &lt; szSizeN; idx++)
        {
           m_xMemory[idx] = b[idx];
        }
  
     }
  
     void swap(Vector &amp;orig)
     {
        using std::swap;
        swap(m_xMemory, orig.m_xMemory);
     }
  
     TBase operator[] (size_t idx) const { return m_xMemory[idx]; }
  
     TBase &amp; operator[] (size_t idx) { return m_xMemory[idx]; }
  
     size_t size() const { return m_xMemory.size(); }
  
     void print()
     {
        size_t szSizeN = size();
        for (size_t idx = 0; idx &lt; szSizeN; idx++)
        {
           std::cout &lt;&lt; "Index=" &lt;&lt; idx &lt;&lt; "\t" &lt;&lt; "Value=" &lt;&lt; m_xMemory[idx] &lt;&lt; std::endl;
  
        }
     }
  
  private:
     void copy(const Vector &amp;orig) 
     {
        m_xMemory = orig.m_xMemory;
     }
  
     std::vector&lt;TBase&gt; m_xMemory;
  };
  
  
  template &lt;typename TBase, typename E1, typename E2&gt;
  Binary_Expression&lt;TBase, std::plus&lt;TBase&gt;, E1, E2&gt; operator+(const BaseExpression&lt;TBase, E1&gt; &amp; xE1, const BaseExpression&lt; TBase, E2&gt; &amp; xE2)
  {
     return Binary_Expression&lt;TBase, std::plus&lt;TBase&gt;, E1, E2&gt;(xE1.self(), xE2.self());
  }
  
  
  int main()
  {
     Vector&lt;double&gt; x1(10);
     Vector&lt;double&gt; x2(10);
     Vector&lt;double&gt; x3(10);
  
     x1 = 7.5;
     x2 = 8.;
     x3 = 4.2;
  
     auto &amp;&amp; intermediate =  x1 + x2;
  
  
  //compil error   
  /*
     for (int i = 0; i&lt; 10; i++)
     {
         intermediate = intermediate + x3;   
     }
     */
     // inspection of the graph here
     Vector&lt;double&gt; result = intermediate + x2;
  
  
     result.print();   
  
  }
  </code></pre>
  
  <p>in fact in my final design I would like to write the following stuff :  </p>
  
  <pre><code>   Vector&lt;double&gt; x1(10);
     Vector&lt;double&gt; x2(10);
     Vector&lt;double&gt; x3(10);
  
     x1 = 7.5;
     x2 = 8.;
     x3 = 4.2;
  
     Vector&lt;double&gt; intermediate = x1 + x2;
     for (int i = 0; i &lt; 5; ++i)
         intermediate = intermediate + x3;
  
     Vector&lt;double&gt; result = x1 + x3 + intermediate;
     // finally into result I have the expression tree, and evaluate method which will make the graph inspection
     result.evaluate();
  </code></pre>
  
  <p>Thanks in advance
  Jonathan</p>