{"id":5163,"date":"2017-02-04T10:44:25","date_gmt":"2017-02-04T10:44:25","guid":{"rendered":"https:\/\/www.modernescpp.com\/index.php\/fold-expressions\/"},"modified":"2023-06-26T12:24:46","modified_gmt":"2023-06-26T12:24:46","slug":"fold-expressions","status":"publish","type":"post","link":"https:\/\/www.modernescpp.com\/index.php\/fold-expressions\/","title":{"rendered":"Fold Expressions"},"content":{"rendered":"<p>With fold expressions, you can implement Haskell functions <span style=\"font-family: courier new,courier;\">foldl, foldr, foldl1<\/span>, and <span style=\"font-family: courier new,courier;\">foldr1 <\/span>directly in C++. These four functions successively reduce a list to a single value.<\/p>\n<p><!--more--><\/p>\n<p>&nbsp;<\/p>\n<h2>Fold expressions<\/h2>\n<p>C++11 supports variadic templates. These are templates that can accept an arbitrary number of template arguments. A parameter pack holds an arbitrary number. Additionally, with C++17, you can directly reduce a parameter pack with a binary operator. Therefore, you can implement Haskell functions <span style=\"font-family: courier new,courier;\">foldl, foldr, foldl1<\/span>, and <span style=\"font-family: courier new,courier;\">foldr1 <\/span>in C++. Let&#8217;s look at how you can reduce a list to a value.<\/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<\/pre>\n<\/td>\n<td>\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #008000;\">\/\/ foldExpression.cpp<\/span>\r\n\r\n<span style=\"color: #0000ff;\">#include &lt;iostream&gt;<\/span>\r\n\r\n<span style=\"color: #2b91af;\">bool<\/span> allVar(){\r\n  <span style=\"color: #0000ff;\">return<\/span> true;\r\n}\r\n\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span> T, <span style=\"color: #0000ff;\">typename<\/span> ...Ts&gt;\r\n<span style=\"color: #2b91af;\">bool<\/span> allVar(T t, Ts ... ts){\r\n  <span style=\"color: #0000ff;\">return<\/span> t &amp;&amp; allVar(ts...);\r\n}\r\n\r\n<span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span>... Args&gt;\r\n<span style=\"color: #2b91af;\">bool<\/span> all(Args... args) { <span style=\"color: #0000ff;\">return<\/span> (... &amp;&amp; args); }\r\n\r\n<span style=\"color: #2b91af;\">int<\/span> main(){\r\n\r\n  std::cout &lt;&lt; std::boolalpha;\r\n\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"allVar(): \"<\/span> &lt;&lt; allVar() &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"all(): \"<\/span> &lt;&lt; all() &lt;&lt; std::endl;\r\n\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"allVar(true): \"<\/span> &lt;&lt; allVar(true) &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"all(true): \"<\/span> &lt;&lt; all(true) &lt;&lt; std::endl;\r\n\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"allVar(true, true, true, false): \"<\/span> &lt;&lt; allVar(true, true, true, false) &lt;&lt; std::endl;\r\n  std::cout &lt;&lt; <span style=\"color: #a31515;\">\"all(true, true, true, false): \"<\/span> &lt;&lt; all(true, true, true, false) &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>Both function templates <span style=\"font-family: courier new,courier;\">allVar<\/span> and <span style=\"font-family: courier new,courier;\">all<\/span> will return at compile time if all arguments are <span style=\"font-family: courier new,courier;\">true. allVar<\/span> uses variadic templates, <span style=\"font-family: courier new,courier;\">all<\/span> variadic templates in combination with fold expressions, at first to <span style=\"font-family: courier new,courier;\">allVar.<\/span> Variadic templates use recursion to evaluate their arguments. Therefore, the function <span style=\"font-family: courier new,courier;\">allVar<\/span> in line 5 is the boundary condition of the empty parameter pack. The recursion takes place in the function template <span style=\"font-family: courier new,courier;\">allVar<\/span> in line 9. The parameter pack is defined thanks to the three dots &#8211; a so-called ellipsis. Parameter packs support two operations. You can pack and unpack them. It is packed in line 9; unpacked in lines 10 and 11. Line 11 needs our full attention. Here, the head of the parameter pack<span style=\"font-family: courier new,courier;\"> t<\/span> is combined with the rest<span style=\"font-family: courier new,courier;\"> ts<\/span> of the parameter pack ts using the binary operator &amp;&amp;. The call <span style=\"font-family: courier new,courier;\">allVar(ts &#8230;)<\/span> triggers the recursion. The call includes a parameter pack that is the original one reduced by the head. Fold expressions make our job easier. With fold expressions, you can directly reduce the parameter pack with the help of the binary operator.<\/p>\n<p>Here is the output of the program.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5161\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/foldingExpressions.png\" alt=\"foldingExpressions\" width=\"600\" height=\"126\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/foldingExpressions.png 853w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/foldingExpressions-300x63.png 300w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/foldingExpressions-768x161.png 768w\" sizes=\"auto, (max-width: 600px) 100vw, 600px\" \/><\/p>\n<\/p>\n<h3>Two variations<\/h3>\n<p>Now to the two variations of fold expression that result in four different forms of fold expressions. At first, fold expression can<\/p>\n<ol>\n<li>have a <strong>default value<\/strong><strong>.<\/strong> That value depends on the binary operator.<strong><br \/><\/strong><\/li>\n<li>be <strong>reduced from the left of the right.<br \/><\/strong><\/li>\n<\/ol>\n<p>&nbsp;<\/p>\n<p>There is a subtle difference between the algorithm <span style=\"font-family: courier new,courier;\">allVar<\/span> and <span style=\"font-family: courier new,courier;\">all.<\/span> <span style=\"font-family: courier new,courier;\">All<\/span> have the default value true for the empty parameter pack.<\/p>\n<p>C++17 supports 32 binary operators in fold expressions: &#8220;<span style=\"font-family: courier new,courier;\"><strong>+ &#8211; * \/ % ^ &amp; | = &lt; &gt; &lt;&lt; &gt;&gt; += -= *= \/= %= ^= &amp;= |= &lt;&lt;= &gt;&gt;= == != &lt;= &gt;= &amp;&amp; || , .* -&gt;*<\/strong><\/span>&#8221; . A few of them have default-values:<\/p>\n<p>&nbsp;<img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5162\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/BinaryOperatorDefault.png\" alt=\"BinaryOperatorDefault\" width=\"500\" height=\"129\" style=\"margin: 15px;\" srcset=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/BinaryOperatorDefault.png 674w, https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/02\/BinaryOperatorDefault-300x77.png 300w\" sizes=\"auto, (max-width: 500px) 100vw, 500px\" \/><\/p>\n<p>You have to provide an initial value for binary operators with no default value. You can specify an initial value for binary operators with a default value.<\/p>\n<p>If the ellipsis stands left of the parameter pack, the parameter pack will be processed from the left. The same holds for right. This is also true if you provide an initial value.<\/p>\n<p>The following table shows the four variations and their Haskell pendants. The C++17 standard requires fold expressions with initial value using the same binary operator <span style=\"font-family: courier new,courier;\">op.<\/span><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\" size-full wp-image-5136\" src=\"https:\/\/www.modernescpp.com\/wp-content\/uploads\/2017\/01\/foldExpressions.png\" alt=\"foldExpressions\" width=\"600\" height=\"261\" style=\"margin: 15px;\" \/><\/p>\n<p>The C++&nbsp; and Haskell variations differ in two points. The C++ version uses the default value as the initial value; the Haskell version uses the first element as the initial value. The C++ version processes the parameter pack at compile-time, and the Haskell version its list at run time.&nbsp;<\/p>\n<p>The small code snippet shows the once more algorithm <span style=\"font-family: courier new,courier;\">all\u2014this<\/span> time, I use <span style=\"font-family: courier new,courier;\">true<\/span> as the initial value.<\/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<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #0000ff;\">template<\/span>&lt;<span style=\"color: #0000ff;\">typename<\/span>... Args&gt;\r\n<span style=\"color: #2b91af;\">bool<\/span> all(Args... args) { <span style=\"color: #0000ff;\">return<\/span> (true &amp;&amp; ... &amp;&amp; args); }\r\n<\/pre>\n<\/div>\n<h2>What&#8217;s next?<\/h2>\n<p>While fold expressions C++ supports the probably most genuine functional algorithm in C++17, the ranges library extends C++20 with three powerful functional concepts. Therefore, the <a href=\"https:\/\/www.modernescpp.com\/index.php\/the-new-ranges-library\">next post<\/a> will be about the ranges library from Eric Niebler that gives lazy evaluation, function composition, and range comprehension a home in functional C++.<\/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>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>With fold expressions, you can implement Haskell functions foldl, foldr, foldl1, and foldr1 directly in C++. These four functions successively reduce a list to a single value.<\/p>\n","protected":false},"author":21,"featured_media":5161,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[365],"tags":[442,508],"class_list":["post-5163","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-functional","tag-fold-expressions","tag-haskell"],"_links":{"self":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5163","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=5163"}],"version-history":[{"count":1,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5163\/revisions"}],"predecessor-version":[{"id":6892,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/posts\/5163\/revisions\/6892"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media\/5161"}],"wp:attachment":[{"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/media?parent=5163"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/categories?post=5163"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.modernescpp.com\/index.php\/wp-json\/wp\/v2\/tags?post=5163"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}