title: A Summation Function For Various Type Arbitrary Nested Iterable Implementation in C++
body: <p>As the title mentioned, I am trying to implement a summation function which can deal with various type arbitrary nested iterable things in C++. The various type here includes the types that can be summed together, and the arbitrary nested iterable things here include for anything that has <code>begin()</code> and <code>end()</code>, such as <code>std::vector</code> and <code>std::array</code>.</p>
  <pre><code>template&lt;typename T&gt;
  concept Summable = requires(T x) { x + x; };
  
  template&lt;typename T&gt;
  concept Iterable = requires(T x)
  {
      x.begin();      // must have `x.begin()` 
      x.end();        // and `x.end()` 
  };
  
  template&lt;typename T&gt; requires Summable&lt;T&gt;
  static T Sum(T inputNumber);        //  Deal with the base case like &quot;Sum(static_cast&lt;int&gt;(1))&quot;
  
  template&lt;class T&gt; requires Iterable&lt;T&gt;
  static auto Sum(const T&amp; numbers);  //  Deal with the iterable case like &quot;Sum(std::vector&lt;long double&gt;{ 1, 1, 1 })&quot;
  
  
  template&lt;class T&gt; requires Summable&lt;T&gt;
  static inline T Sum(T inputNumber)
  {
      return inputNumber;
  }
  
  template&lt;class T&gt;  requires Iterable&lt;T&gt;
  static inline auto Sum(const T&amp; numbers)
  {
      long double sumResult = 0.0;
      for (auto&amp; element : numbers)
      {
          sumResult = sumResult + Sum(element);
      }
      return sumResult;
  }
  </code></pre>
  <p>The test cases are listed as below.</p>
  <pre><code>long double testNumber = 1;
      
  std::vector&lt;decltype(testNumber)&gt; testVector1;
  testVector1.push_back(testNumber);
  testVector1.push_back(testNumber);
  testVector1.push_back(testNumber);
  std::cout &lt;&lt; Sum(testVector1) &lt;&lt; std::endl;
  
  std::vector&lt;decltype(testVector1)&gt; testVector2;
  testVector2.push_back(testVector1);
  testVector2.push_back(testVector1);
  testVector2.push_back(testVector1);
  std::cout &lt;&lt; Sum(testVector2) &lt;&lt; std::endl;
  
  std::vector&lt;decltype(testVector2)&gt; testVector3;
  testVector3.push_back(testVector2);
  testVector3.push_back(testVector2);
  testVector3.push_back(testVector2);
  std::cout &lt;&lt; Sum(testVector3) &lt;&lt; std::endl;
  
  //  std::array test case
  std::array&lt;long double, 90&gt; numberArray;
  for (size_t i = 0; i &lt; 90; i++)
  {
      numberArray[i] = 1;
  }
  std::cout &lt;&lt; std::to_string(Sum(numberArray)) + &quot;\n&quot;;
  </code></pre>
  <p>However, there are some defects in the above <code>Sum</code> function</p>
  <ol>
  <li><p>The type of return value in the implementation for the iterable case is always <code>long double</code>. It seems that this return type should be as same as the input iterable value type.</p>
  </li>
  <li><p>When it comes to the type <code>std::complex</code> which is not a built-in numeric types, this <code>sum</code> function can't work.</p>
  </li>
  </ol>
  <p>I tried to modified the <code>Sum</code> function into the following version.</p>
  <pre><code>template&lt;class T&gt;  requires Iterable&lt;T&gt;
  static inline auto Sum(const T&amp; numbers)
  {
      typename std::iterator_traits&lt;T::iterator&gt;::value_type sumResult = 0.0;     //  Update &quot;long double&quot; into &quot;typename std::iterator_traits&lt;T::iterator&gt;::value_type&quot;
      for (auto&amp; element : numbers)
      {
          sumResult = sumResult + Sum(element);
      }
      return sumResult;
  }
  </code></pre>
  <p>Then, it works well in <code>std::vector&lt;&gt;</code> case. However, the <code>typename std::iterator_traits&lt;T::iterator&gt;::value_type</code> can not handle the multi-nested iterable case, such as <code>std::vector&lt;std::vector&lt;std::complex&gt;&gt;</code> or <code>std::vector&lt;std::vector&lt;std::vector&lt;std::complex&gt;&gt;&gt;</code>. Is there any possible solution to this problem?</p>
  <p>All suggestions are welcome.</p>