{"id":5187,"date":"2017-02-14T18:39:39","date_gmt":"2017-02-14T18:39:39","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/expression-templates\/"},"modified":"2023-06-26T12:22:58","modified_gmt":"2023-06-26T12:22:58","slug":"expression-templates","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/expression-templates\/","title":{"rendered":"Expression Templates"},"content":{"rendered":"<p>Expression templates are &#8220;structures representing a computation at compile-time, which are evaluated only as needed to produce efficient code for the entire computation&#8221; (<a href=\"https:\/\/en.wikipedia.org\/wiki\/Expression_templates\">https:\/\/en.wikipedia.org\/wiki\/Expression_templates<\/a>). As needed, now we are at the center of lazy evaluation and the center of this post.<\/p>\n<p><!--more--><\/p>\n<p>What problem do expression templates solve? Thanks to expression templates, you can eliminate superfluous temporary objects in expressions. What do I mean by superfluous temporary objects? My implementation of the class <span style=\"font-family: courier new,courier;\">MyVector.<\/span><\/p>\n<h2>A first naive approach<\/h2>\n<p><span style=\"font-family: courier new,courier;\">MyVector<\/span> is a simple wrapper for a&nbsp; <span style=\"font-family: courier new,courier;\">std::vector&lt;T&gt;.<\/span> The wrapper has two constructors (lines 12 and 15), knows its length (lines 18 &#8211; 20), and supports the reading (lines 23 &#8211; 25) and writing (lines 27 &#8211; 29) index access.<\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"> 1\r\n 2\r\n 3\r\n 4\r\n 5\r\n 6\r\n 7\r\n 8\r\n 9\r\n10\r\n11\r\n12\r\n13\r\n14\r\n15\r\n16\r\n17\r\n18\r\n19\r\n20\r\n21\r\n22\r\n23\r\n24\r\n25\r\n26\r\n27\r\n28\r\n29\r\n30\r\n31\r\n32\r\n33\r\n34\r\n35\r\n36\r\n37\r\n38\r\n39\r\n40\r\n41\r\n42\r\n43\r\n44\r\n45\r\n46\r\n47\r\n48\r\n49\r\n50\r\n51\r\n52\r\n53\r\n54\r\n55\r\n56\r\n57\r\n58\r\n59\r\n60\r\n61\r\n62\r\n63\r\n64\r\n65\r\n66\r\n67\r\n68\r\n69\r\n70\r\n71\r\n72\r\n73\r\n74\r\n75<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ vectorArithmeticOperatorOverloading.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;vector&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">MyVector<\/span>{\r\n  std::vector&lt;T&gt; cont;   \r\n\r\npublic:\r\n  <span style=\"color: #008000;\">\/\/ MyVector with initial size<\/span>\r\n  MyVector(<span style=\"color: #0000ff;\">const<\/span> std::<span style=\"color: #2b91af;\">size_t<\/span> n) : cont(n){}  \r\n\r\n  <span style=\"color: #008000;\">\/\/ MyVector with initial size and value<\/span>\r\n  MyVector(<span style=\"color: #0000ff;\">const<\/span> std::<span style=\"color: #2b91af;\">size_t<\/span> n, <span style=\"color: #0000ff;\">const<\/span> <span style=\"color: #2b91af;\">double<\/span> initialValue) : cont(n, initialValue){}\r\n  \r\n  <span style=\"color: #008000;\">\/\/ size of underlying container<\/span>\r\n  std::<span style=\"color: #2b91af;\">size_t<\/span> size() <span style=\"color: #0000ff;\">const<\/span>{ \r\n    <span style=\"color: #0000ff;\">return<\/span> cont.size(); \r\n  }\r\n\r\n  <span style=\"color: #008000;\">\/\/ index operators<\/span>\r\n  T <span style=\"color: #0000ff;\">operator<\/span>[](<span style=\"color: #0000ff;\">const<\/span> std::<span style=\"color: #2b91af;\">size_t<\/span> i) <span style=\"color: #0000ff;\">const<\/span>{ \r\n    <span style=\"color: #0000ff;\">return<\/span> cont[i]; \r\n  }\r\n\r\n  T&amp; <span style=\"color: #0000ff;\">operator<\/span>[](<span style=\"color: #0000ff;\">const<\/span> std::<span style=\"color: #2b91af;\">size_t<\/span> i){ \r\n    <span style=\"color: #0000ff;\">return<\/span> cont[i]; \r\n  }\r\n\r\n};\r\n\r\n<span style=\"color: #008000;\">\/\/ function template for the + operator<\/span>\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt; \r\nMyVector&lt;T&gt; <span style=\"color: #0000ff;\">operator<\/span>+ (<span style=\"color: #0000ff;\">const<\/span> MyVector&lt;T&gt;&amp; a, <span style=\"color: #0000ff;\">const<\/span> MyVector&lt;T&gt;&amp; b){\r\n  MyVector&lt;T&gt; result(a.size());\r\n  <span style=\"color: #0000ff;\">for<\/span> (std::<span style=\"color: #2b91af;\">size_t<\/span> s= 0; s &lt;= a.size(); ++s){\r\n    result[s]= a[s]+b[s];\r\n  }\r\n  <span style=\"color: #0000ff;\">return<\/span> result;\r\n}\r\n\r\n<span style=\"color: #008000;\">\/\/ function template for the * operator<\/span>\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\nMyVector&lt;T&gt; <span style=\"color: #0000ff;\">operator<\/span>* (<span style=\"color: #0000ff;\">const<\/span> MyVector&lt;T&gt;&amp; a, <span style=\"color: #0000ff;\">const<\/span> MyVector&lt;T&gt;&amp; b){\r\n   MyVector&lt;T&gt; result(a.size());\r\n  <span style=\"color: #0000ff;\">for<\/span> (std::<span style=\"color: #2b91af;\">size_t<\/span> s= 0; s &lt;= a.size(); ++s){\r\n    result[s]= a[s]*b[s]; \r\n  }\r\n  <span style=\"color: #0000ff;\">return<\/span> result;\r\n}\r\n\r\n<span style=\"color: #008000;\">\/\/ function template for &lt;&lt; operator<\/span>\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\nstd::ostream&amp; <span style=\"color: #0000ff;\">operator<\/span>&lt;&lt;(std::ostream&amp; os, <span style=\"color: #0000ff;\">const<\/span> MyVector&lt;T&gt;&amp; cont){  \r\n  std::cout &lt;&lt; std::endl;\r\n  <span style=\"color: #0000ff;\">for<\/span> (<span style=\"color: #2b91af;\">int<\/span> i=0; i&lt;cont.size(); ++i) {\r\n    os &lt;&lt; cont[i] &lt;&lt; <span style=\"color: #a31515;\">' '<\/span>;\r\n  }\r\n  os &lt;&lt; std::endl;\r\n  <span style=\"color: #0000ff;\">return<\/span> os;\r\n} \r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  MyVector&lt;<span style=\"color: #2b91af;\">double<\/span>&gt; x(10,5.4);\r\n  MyVector&lt;<span style=\"color: #2b91af;\">double<\/span>&gt; y(10,10.3);\r\n\r\n  MyVector&lt;<span style=\"color: #2b91af;\">double<\/span>&gt; result(10);\r\n  \r\n  result= x+x + y*y;\r\n  \r\n  std::cout &lt;&lt; result &lt;&lt; std::endl;\r\n  \r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>Thanks to the overloaded + operator (lines 34 &#8211; 41), the overloaded&nbsp; * operator (lines 44 &#8211; 51), and the overloaded output operator (lines 54 &#8211; 62), the objects <span style=\"font-family: courier new,courier;\">x, y<\/span>, and <span style=\"font-family: courier new,courier;\">result<\/span> feel like numbers.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5181\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/vectorArithmeticOperatorOverloading.png\" alt=\"vectorArithmeticOperatorOverloading\" width=\"677\" height=\"130\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/vectorArithmeticOperatorOverloading.png 677w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/vectorArithmeticOperatorOverloading-300x58.png 300w\" sizes=\"auto, (max-width: 677px) 100vw, 677px\" \/><\/p>\n<p>Why is this implementation naive? The answer is in the expression&nbsp; <span style=\"font-family: courier new,courier;\">result=<\/span> <span style=\"font-family: courier new,courier;\">x+x + y*y.&nbsp;<\/span> Three temporary objects are needed to evaluate the expression to hold the result of each arithmetic sub-expression.<span style=\"font-family: courier new,courier;\"><br \/><\/span><\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5182\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/Temporaries.png\" alt=\"Temporaries\" width=\"400\" height=\"263\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/Temporaries.png 487w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/Temporaries-300x197.png 300w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>How can I get rid of the temporaries? The idea is simple. Instead of performing the vector operations greedy, I lazily create the expression tree for result[i] at compile time.<\/p>\n<h2>Expression templates&nbsp;<\/h2>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5183\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/ExpressionTree.png\" alt=\"ExpressionTree\" width=\"400\" height=\"206\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/ExpressionTree.png 780w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/ExpressionTree-300x155.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/ExpressionTree-768x396.png 768w\" sizes=\"auto, (max-width: 400px) 100vw, 400px\" \/><\/p>\n<p>There are no temporaries needed for the expression <span style=\"font-family: courier new,courier;\">result[i]=<\/span> <span style=\"font-family: courier new,courier;\">x[i]+x[i] + y[i]*y[i]<span style=\"font-family: arial,helvetica,sans-serif;\">.&nbsp; <\/span><\/span>The assignment triggers the evaluation. Sadly, even in this simple usage, the code is not so easy to digest. <span style=\"font-family: courier new,courier;\"><span style=\"font-family: arial,helvetica,sans-serif;\"><br \/><\/span><\/span><\/p>\n<p>&nbsp;<\/p>\n<p><!-- HTML generated using hilite.me --><\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; gray;border-width: .1em .1em .1em .8em;\">\n<table>\n<tbody>\n<tr>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\">  1\r\n  2\r\n  3\r\n  4\r\n  5\r\n  6\r\n  7\r\n  8\r\n  9\r\n 10\r\n 11\r\n 12\r\n 13\r\n 14\r\n 15\r\n 16\r\n 17\r\n 18\r\n 19\r\n 20\r\n 21\r\n 22\r\n 23\r\n 24\r\n 25\r\n 26\r\n 27\r\n 28\r\n 29\r\n 30\r\n 31\r\n 32\r\n 33\r\n 34\r\n 35\r\n 36\r\n 37\r\n 38\r\n 39\r\n 40\r\n 41\r\n 42\r\n 43\r\n 44\r\n 45\r\n 46\r\n 47\r\n 48\r\n 49\r\n 50\r\n 51\r\n 52\r\n 53\r\n 54\r\n 55\r\n 56\r\n 57\r\n 58\r\n 59\r\n 60\r\n 61\r\n 62\r\n 63\r\n 64\r\n 65\r\n 66\r\n 67\r\n 68\r\n 69\r\n 70\r\n 71\r\n 72\r\n 73\r\n 74\r\n 75\r\n 76\r\n 77\r\n 78\r\n 79\r\n 80\r\n 81\r\n 82\r\n 83\r\n 84\r\n 85\r\n 86\r\n 87\r\n 88\r\n 89\r\n 90\r\n 91\r\n 92\r\n 93\r\n 94\r\n 95\r\n 96\r\n 97\r\n 98\r\n 99\r\n100\r\n101\r\n102\r\n103\r\n104\r\n105\r\n106\r\n107\r\n108\r\n109\r\n110\r\n111\r\n112\r\n113\r\n114\r\n115\r\n116\r\n117\r\n118\r\n119\r\n120\r\n121\r\n122\r\n123\r\n124\r\n125<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ vectorArithmeticExpressionTemplates.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;cassert&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n<span style=\"color: #0000ff;\">#include &lt;vector&gt;<\/span>\r\n\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T, <span style=\"color: #0000ff;\">typename<\/span> Cont= std::vector&lt;T&gt; &gt;\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">MyVector<\/span>{\r\n  Cont cont;   \r\n\r\npublic:\r\n  <span style=\"color: #008000;\">\/\/ MyVector with initial size<\/span>\r\n  MyVector(<span style=\"color: #0000ff;\">const<\/span> std::<span style=\"color: #2b91af;\">size_t<\/span> n) : cont(n){}\r\n\r\n  <span style=\"color: #008000;\">\/\/ MyVector with initial size and value<\/span>\r\n  MyVector(<span style=\"color: #0000ff;\">const<\/span> std::<span style=\"color: #2b91af;\">size_t<\/span> n, <span style=\"color: #0000ff;\">const<\/span> <span style=\"color: #2b91af;\">double<\/span> initialValue) : cont(n, initialValue){}\r\n\r\n  <span style=\"color: #008000;\">\/\/ Constructor for underlying container<\/span>\r\n  MyVector(<span style=\"color: #0000ff;\">const<\/span> Cont&amp; other) : cont(other){}\r\n\r\n  <span style=\"color: #008000;\">\/\/ assignment operator for MyVector of different type<\/span>\r\n  <span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T2, <span style=\"color: #0000ff;\">typename<\/span> R2&gt;\r\n  MyVector&amp; <span style=\"color: #0000ff;\">operator<\/span>=(<span style=\"color: #0000ff;\">const<\/span> MyVector&lt;T2, R2&gt;&amp; other){\r\n    assert(size() == other.size());\r\n    <span style=\"color: #0000ff;\">for<\/span> (std::<span style=\"color: #2b91af;\">size_t<\/span> i = 0; i &lt; cont.size(); ++i) cont[i] = other[i];\r\n    <span style=\"color: #0000ff;\">return<\/span> *<span style=\"color: #0000ff;\">this<\/span>;\r\n  }\r\n\r\n  <span style=\"color: #008000;\">\/\/ size of underlying container<\/span>\r\n  std::<span style=\"color: #2b91af;\">size_t<\/span> size() <span style=\"color: #0000ff;\">const<\/span>{ \r\n    <span style=\"color: #0000ff;\">return<\/span> cont.size(); \r\n  }\r\n\r\n  <span style=\"color: #008000;\">\/\/ index operators<\/span>\r\n  T <span style=\"color: #0000ff;\">operator<\/span>[](<span style=\"color: #0000ff;\">const<\/span> std::<span style=\"color: #2b91af;\">size_t<\/span> i) <span style=\"color: #0000ff;\">const<\/span>{ \r\n    <span style=\"color: #0000ff;\">return<\/span> cont[i]; \r\n  }\r\n\r\n  T&amp; <span style=\"color: #0000ff;\">operator<\/span>[](<span style=\"color: #0000ff;\">const<\/span> std::<span style=\"color: #2b91af;\">size_t<\/span> i){ \r\n    <span style=\"color: #0000ff;\">return<\/span> cont[i]; \r\n  }\r\n\r\n  <span style=\"color: #008000;\">\/\/ returns the underlying data<\/span>\r\n  <span style=\"color: #0000ff;\">const<\/span> Cont&amp; data() <span style=\"color: #0000ff;\">const<\/span>{ \r\n    <span style=\"color: #0000ff;\">return<\/span> cont; \r\n  }\r\n\r\n  Cont&amp; data(){ \r\n    <span style=\"color: #0000ff;\">return<\/span> cont; \r\n  }\r\n};\r\n\r\n<span style=\"color: #008000;\">\/\/ MyVector + MyVector<\/span>\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T, <span style=\"color: #0000ff;\">typename<\/span> Op1 , <span style=\"color: #0000ff;\">typename<\/span> Op2&gt;\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">MyVectorAdd<\/span>{\r\n  <span style=\"color: #0000ff;\">const<\/span> Op1&amp; op1;\r\n  <span style=\"color: #0000ff;\">const<\/span> Op2&amp; op2;\r\n\r\npublic:\r\n  MyVectorAdd(<span style=\"color: #0000ff;\">const<\/span> Op1&amp; a, <span style=\"color: #0000ff;\">const<\/span> Op2&amp; b): op1(a), op2(b){}\r\n\r\n  T <span style=\"color: #0000ff;\">operator<\/span>[](<span style=\"color: #0000ff;\">const<\/span> std::<span style=\"color: #2b91af;\">size_t<\/span> i) <span style=\"color: #0000ff;\">const<\/span>{ \r\n    <span style=\"color: #0000ff;\">return<\/span> op1[i] + op2[i]; \r\n  }\r\n\r\n  std::<span style=\"color: #2b91af;\">size_t<\/span> size() <span style=\"color: #0000ff;\">const<\/span>{ \r\n    <span style=\"color: #0000ff;\">return<\/span> op1.size(); \r\n  }\r\n};\r\n\r\n<span style=\"color: #008000;\">\/\/ elementwise MyVector * MyVector<\/span>\r\n<span style=\"color: #0000ff;\">template<\/span>&lt; <span style=\"color: #0000ff;\">typename<\/span> T, <span style=\"color: #0000ff;\">typename<\/span> Op1 , <span style=\"color: #0000ff;\">typename<\/span> Op2 &gt;\r\n<span style=\"color: #0000ff;\">class<\/span> <span style=\"color: #2b91af;\">MyVectorMul<\/span> {\r\n  <span style=\"color: #0000ff;\">const<\/span> Op1&amp; op1;\r\n  <span style=\"color: #0000ff;\">const<\/span> Op2&amp; op2;\r\n\r\npublic:\r\n  MyVectorMul(<span style=\"color: #0000ff;\">const<\/span> Op1&amp; a, <span style=\"color: #0000ff;\">const<\/span> Op2&amp; b ): op1(a), op2(b){}\r\n\r\n  T <span style=\"color: #0000ff;\">operator<\/span>[](<span style=\"color: #0000ff;\">const<\/span> std::<span style=\"color: #2b91af;\">size_t<\/span> i) <span style=\"color: #0000ff;\">const<\/span>{ \r\n    <span style=\"color: #0000ff;\">return<\/span> op1[i] * op2[i]; \r\n  }\r\n\r\n  std::<span style=\"color: #2b91af;\">size_t<\/span> size() <span style=\"color: #0000ff;\">const<\/span>{ \r\n    <span style=\"color: #0000ff;\">return<\/span> op1.size(); \r\n  }\r\n};\r\n\r\n<span style=\"color: #008000;\">\/\/ function template for the + operator<\/span>\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T, <span style=\"color: #0000ff;\">typename<\/span> R1, <span style=\"color: #0000ff;\">typename<\/span> R2&gt;\r\nMyVector&lt;T, MyVectorAdd&lt;T, R1, R2&gt; &gt;\r\n<span style=\"color: #0000ff;\">operator<\/span>+ (<span style=\"color: #0000ff;\">const<\/span> MyVector&lt;T, R1&gt;&amp; a, <span style=\"color: #0000ff;\">const<\/span> MyVector&lt;T, R2&gt;&amp; b){\r\n  <span style=\"color: #0000ff;\">return<\/span> MyVector&lt;T, MyVectorAdd&lt;T, R1, R2&gt; &gt;(MyVectorAdd&lt;T, R1, R2 &gt;(a.data(), b.data()));\r\n}\r\n\r\n<span style=\"color: #008000;\">\/\/ function template for the * operator<\/span>\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T, <span style=\"color: #0000ff;\">typename<\/span> R1, <span style=\"color: #0000ff;\">typename<\/span> R2&gt;\r\nMyVector&lt;T, MyVectorMul&lt; T, R1, R2&gt; &gt;\r\n<span style=\"color: #0000ff;\">operator<\/span>* (<span style=\"color: #0000ff;\">const<\/span> MyVector&lt;T, R1&gt;&amp; a, <span style=\"color: #0000ff;\">const<\/span> MyVector&lt;T, R2&gt;&amp; b){\r\n   <span style=\"color: #0000ff;\">return<\/span> MyVector&lt;T, MyVectorMul&lt;T, R1, R2&gt; &gt;(MyVectorMul&lt;T, R1, R2 &gt;(a.data(), b.data()));\r\n}\r\n\r\n<span style=\"color: #008000;\">\/\/ function template for &lt; operator<\/span>\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T&gt;\r\nstd::ostream&amp; <span style=\"color: #0000ff;\">operator<\/span>&lt;&lt;(std::ostream&amp; os, <span style=\"color: #0000ff;\">const<\/span> MyVector&lt;T&gt;&amp; cont){  \r\n  std::cout &lt;&lt; std::endl;\r\n  <span style=\"color: #0000ff;\">for<\/span> (<span style=\"color: #2b91af;\">int<\/span> i=0; i&lt;cont.size(); ++i) {\r\n    os &lt;&lt; cont[i] &lt;&lt; <span style=\"color: #a31515;\">' '<\/span>;\r\n  }\r\n  os &lt;&lt; std::endl;\r\n  <span style=\"color: #0000ff;\">return<\/span> os;\r\n} \r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  MyVector&lt;<span style=\"color: #2b91af;\">double<\/span>&gt; x(10,5.4);\r\n  MyVector&lt;<span style=\"color: #2b91af;\">double<\/span>&gt; y(10,10.3);\r\n\r\n  MyVector&lt;<span style=\"color: #2b91af;\">double<\/span>&gt; result(10);\r\n  \r\n  result= x+x + y*y;\r\n  \r\n  std::cout &lt;&lt; result &lt;&lt; std::endl;\r\n  \r\n}\r\n<\/pre>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<p>&nbsp;<\/p>\n<p>The key difference between the first naive implementation and this implementation with expression templates is that the overloaded + and + operators return in the case of the expression tree proxy objects. These proxies represent the expression tree (lines 94 and 100). The expression tree is only created but not evaluated. Lazy, of course. The assignment operator (lines 22 &#8211; 27) triggers the evaluation of the expression tree that needs no temporaries.<\/p>\n<p>The result is the same.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5184\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/vectorArithmeticExpressionTemplates.png\" alt=\"vectorArithmeticExpressionTemplates\" width=\"677\" height=\"130\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/vectorArithmeticExpressionTemplates.png 677w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/vectorArithmeticExpressionTemplates-300x58.png 300w\" sizes=\"auto, (max-width: 677px) 100vw, 677px\" \/><\/p>\n<p>&nbsp;<\/p>\n<p>Suppose you were not able to follow my explanation, no problem. The assembler code of the program <span style=\"font-family: courier new,courier;\">vectorArithmeticExpressionTemplates.cpp <\/span>shows the magic.<\/p>\n<\/p>\n<h3>Under the hood<\/h3>\n<p>Thanks to the compiler explorer on&nbsp; <a href=\"https:\/\/godbolt.org\/\">godbolt.org, <\/a>it&#8217;s quite easy to have the assembler instructions.<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5185\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/godbolt.png\" alt=\"godbolt\" width=\"700\" height=\"176\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/godbolt.png 921w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/godbolt-300x75.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/godbolt-768x193.png 768w\" sizes=\"auto, (max-width: 700px) 100vw, 700px\" \/><\/p>\n<p>The expression tree in line 60 is not so beautiful. But with a sharp eye, you can see the structure. For simplicity reasons, I ignored the <span style=\"font-family: courier new,courier;\">std::allocator<\/span> in my graphic.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5186\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/Exression.png\" alt=\"Exression\" width=\"600\" height=\"286\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/Exression.png 1254w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/Exression-300x143.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/Exression-1024x488.png 1024w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/Exression-768x366.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<h2>What&#8217;s next?<\/h2>\n<p>With the next post, I will start the rework of my blog. That means I will rework old posts and write new posts to complete my stories. I&nbsp; will start in the <a href=\"https:\/\/www.modernescpp.com\/index.php\/multithreading-in-c-17-and-c-20\">next post <\/a>with the multithreading features of C++17 and C++20. Here is an <a href=\"https:\/\/www.modernescpp.com\/index.php\/der-einstieg-in-modernes-c\">overview<\/a> of all my posts.<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Expression templates are &#8220;structures representing a computation at compile-time, which are evaluated only as needed to produce efficient code for the entire computation&#8221; (https:\/\/en.wikipedia.org\/wiki\/Expression_templates). As needed, now we are at the center of lazy evaluation and the center of this post.<\/p>\n","protected":false},"author":21,"featured_media":5181,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[365],"tags":[424],"class_list":["post-5187","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-functional","tag-expression-templates"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5187","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/users\/21"}],"replies":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/comments?post=5187"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5187\/revisions"}],"predecessor-version":[{"id":6887,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5187\/revisions\/6887"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5181"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5187"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5187"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5187"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}