title: Ambiguous recursive template function
body: <p>In C++11, I need to call a function recursively from <code>0,...,n</code> (where <code>n</code> is a compile time constant). This is the structure of the problem, which appears to be fatally flawed:</p>
  
  <pre><code>#include "Eigen/Dense"
  
  template&lt;size_t i&gt;
  struct Int {
  };
  
  template&lt;size_t d, typename C, typename X&gt;
  constexpr X eval(const C &amp;c, const X &amp;x, const Int&lt;d&gt; &amp;, const Int&lt;C::SizeAtCompileTime - 1 - d&gt; &amp;) {
      return 1;
  }
  
  template&lt;size_t d, typename C, typename X, size_t i&gt;
  constexpr X eval(const C &amp;c, const X &amp;x, const Int&lt;d&gt; &amp;, const Int&lt;i&gt; &amp;) {
      return x * eval(c, x, Int&lt;d&gt;(), Int&lt;i + 1&gt;());
  }
  
  int main() {
      const size_t d = 1;
      const Eigen::Matrix&lt;double, 1, 7&gt; c = Eigen::Matrix&lt;double,1,7&gt;::Zero();
      const double x = 5;
      eval(c, x, Int&lt;d&gt;(), Int&lt;0&gt;());
  }
  </code></pre>
  
  <p>and the full error message: </p>
  
  <pre><code>/usr/bin/cmake --build /mnt/c/Dropbox/clion/recursion/cmake-build-debug --target recursion -- -j 4
  Scanning dependencies of target recursion
  [ 50%] Building CXX object CMakeFiles/recursion.dir/main.cpp.o
  /mnt/c/Dropbox/clion/recursion/main.cpp: In instantiation of 'constexpr X eval(const C&amp;, const X&amp;, const Int&lt;d&gt;&amp;, const Int&lt;i&gt;&amp;) [with long unsigned int d = 1ul; C = Eigen::Matrix&lt;double, 1, 7&gt;; X = double; long unsigned int i = 4ul]':
  /mnt/c/Dropbox/clion/recursion/main.cpp:14:20:   recursively required from 'constexpr X eval(const C&amp;, const X&amp;, const Int&lt;d&gt;&amp;, const Int&lt;i&gt;&amp;) [with long unsigned int d = 1ul; C = Eigen::Matrix&lt;double, 1, 7&gt;; X = double; long unsigned int i = 1ul]'
  /mnt/c/Dropbox/clion/recursion/main.cpp:14:20:   required from 'constexpr X eval(const C&amp;, const X&amp;, const Int&lt;d&gt;&amp;, const Int&lt;i&gt;&amp;) [with long unsigned int d = 1ul; C = Eigen::Matrix&lt;double, 1, 7&gt;; X = double; long unsigned int i = 0ul]'
  /mnt/c/Dropbox/clion/recursion/main.cpp:21:34:   required from here
  /mnt/c/Dropbox/clion/recursion/main.cpp:14:20: error: call of overloaded 'eval(const Eigen::Matrix&lt;double, 1, 7&gt;&amp;, const double&amp;, Int&lt;1ul&gt;, Int&lt;5ul&gt;)' is ambiguous
       return x * eval(c, x, Int&lt;d&gt;(), Int&lt;i + 1&gt;());
                      ^
  /mnt/c/Dropbox/clion/recursion/main.cpp:8:13: note: candidate: constexpr X eval(const C&amp;, const X&amp;, const Int&lt;d&gt;&amp;, const Int&lt;((C:: SizeAtCompileTime - 1) - d)&gt;&amp;) [with long unsigned int d = 1ul; C = Eigen::Matrix&lt;double, 1, 7&gt;; X = double]
   constexpr X eval(const C &amp;c, const X &amp;x, const Int&lt;d&gt; &amp;, const Int&lt;C::SizeAtCompileTime - 1 - d&gt; &amp;) {
               ^
  /mnt/c/Dropbox/clion/recursion/main.cpp:13:13: note: candidate: constexpr X eval(const C&amp;, const X&amp;, const Int&lt;d&gt;&amp;, const Int&lt;i&gt;&amp;) [with long unsigned int d = 1ul; C = Eigen::Matrix&lt;double, 1, 7&gt;; X = double; long unsigned int i = 5ul]
   constexpr X eval(const C &amp;c, const X &amp;x, const Int&lt;d&gt; &amp;, const Int&lt;i&gt; &amp;) {
               ^
  /mnt/c/Dropbox/clion/recursion/main.cpp:15:1: error: body of constexpr function 'constexpr X eval(const C&amp;, const X&amp;, const Int&lt;d&gt;&amp;, const Int&lt;i&gt;&amp;) [with long unsigned int d = 1ul; C = Eigen::Matrix&lt;double, 1, 7&gt;; X = double; long unsigned int i = 4ul]' not a return-statement
   }
  </code></pre>
  
  <p>My understanding was that in the last line, <code>x * eval(c, x, Int&lt;d&gt;(), Int&lt;i + 1&gt;());</code>, when <code>i+1 = n</code>, then the first function which returns 1 would be chosen, but the compiler says that the call is ambiguous. Could somebody explain why? and how to fix this?  </p>
  
  <p>Note: I am aware that you cannot partially specialize a template function. I am trying to mimic the behavior instead with overloading. </p>
  
  <hr>
  
  <h2>EDIT</h2>
  
  <p>It seems that the issue lies in the expansion of <code>C::SizeAtCompileTime</code>. When I hard-code that constant, the program compiles. Is there a general C++ rule indicating why that is happening? or is that something that is Eigen specific? </p>