title: constexpr initialization with a lamba function
body: <h2>Context</h2>
  <p>I'm writing a math lib for training. Right now I'm working on the Matrix class.
  I'm trying to make a <code>identityMatrix()</code> function. This is a templated function that builds and returns a identity matrix. Right now my code is:</p>
  <pre class="lang-cpp prettyprint-override"><code>template&lt;index_t N, typename Scalar = double&gt;
  constexpr inline static const Matrix&lt;N, N, Scalar&gt; identityMatrix() noexcept
  {
      constexpr static Matrix&lt;N, N, Scalar&gt; id = []
      {
          Matrix&lt;N, N, Scalar&gt; m(0);
          for (index_t i = 0; i &lt; N; i++)
          {
              m.at(i, i) = static_cast&lt;Scalar&gt;(1.0);
          }
          return m;
      }();
      return id;
  }
  </code></pre>
  <p>I'm trying to make it so the matrix is build once only if needed, any later reference to the function returns a function local static const object. As the initialization is complex I'm using a lambda and calling it right away.
  The <code>Matrix</code> definition is as following:</p>
  <pre class="lang-cpp prettyprint-override"><code>using index_t = uint32_t;
  #define FOR(i, N) for(index_t i = 0; i &lt; N; ++i)
  #define FORiN(N) FOR(i, N)
  template&lt;index_t ROWS, index_t COLS = ROWS, typename Scalar = double&gt;
  struct Matrix 
  {
      static constexpr auto BUFFER_SIZE = ROWS * COLS;
      Scalar buffer[BUFFER_SIZE];
      //...
      constexpr Matrix() noexcept = default;
  
      constexpr Matrix(const Scalar (&amp;init_data)[BUFFER_SIZE]) noexcept
      {
          memcpy_s(buffer, BUFFER_SIZE * sizeof Scalar, &amp;init_data , BUFFER_SIZE * sizeof Scalar);
      }
      constexpr Matrix(const std::initializer_list&lt;std::initializer_list&lt;Scalar&gt;&gt;&amp; init_data) 
      {
          static_assert(init_data.size() == ROWS &amp;&amp; init_data.begin()-&gt;size() == COLS);
          FOR(row_index, ROWS) 
          {
              Scalar* src_row = &amp;init_data.begin()[row_index];
              Scalar* dst_row = &amp;buffer[row_index * COLS];
              constexpr index_t row_size_bytes = COLS * sizeof Scalar;
              memcpy_s(dst_row, row_size_bytes, src_row, row_size_bytes);
          }
      }
      constexpr Matrix(Scalar homogenuos_value) noexcept
      {
          std::fill_n(buffer, BUFFER_SIZE, homogenuos_value);
      }
      constexpr Matrix(const Matrix&amp; rhs) noexcept 
      {
          FOR(i, BUFFER_SIZE)
              buffer[i] = rhs.buffer[i];
      }
      inline constexpr static index_t indexOf(index_t col, index_t row) { return row * COLS + col; }
  
      inline constexpr Scalar&amp; at(index_t row, index_t col) { return buffer[indexOf(row, col)]; }
      inline constexpr const Scalar&amp; at(index_t row, index_t col) const { return buffer[indexOf(row, col)]; }
      //... more operators and stuff
  };
  </code></pre>
  <h2>The problem</h2>
  <p>The test code i'm writting to test my matrix code is as following:</p>
  <pre class="lang-cpp prettyprint-override"><code>    constexpr auto id = identityMatrix&lt;3&gt;();
      constexpr auto manual_id = Matrix&lt;3, 3&gt;({ 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0 });
      static_assert(id == manual_id);
      print(id);
  </code></pre>
  <p>Visual Studio gives me this:
  <a href="https://i.stack.imgur.com/FI6TC.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/FI6TC.png" alt="" /></a>
  And also:</p>
  <p><a href="https://i.stack.imgur.com/4PGaY.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/4PGaY.png" alt="" /></a></p>
  <h2>Why</h2>
  <p>Why is this not working? I have make <strong>everything</strong> <code>constexpr</code> this should be constant at compile time. The compiler should be able to make this. What am I missing? What am I doing wrong?</p>
  <h2>Enviroment</h2>
  <p>I'm using</p>
  <blockquote>
  <p>Microsoft Visual Studio Professional 2019 - version 16.4.2<br />
  Platform toolset: Visual Studio 2019 (v142)<br />
  C++ Language Standard: Preview - Features from the Latest C++ Working Draft (std:c++latest)<br />
  Today's date: 9 june 2020</p>
  </blockquote>