title: How to initialise a floating point array at compile time?
body: <p>I have found two good approaches to initialise integral arrays at compile times <a href="https://stackoverflow.com/a/12108694">here</a> and <a href="https://stackoverflow.com/a/2981617">here</a>.</p>
  
  <p>Unfortunately, neither can be converted to initialise a float array straightforward; I find that I am not fit enough in template metaprogramming to solve this through trial-and-error.</p>
  
  <p>First let me declare a use-case:</p>
  
  <pre><code>constexpr unsigned int SineLength  = 360u;
  constexpr unsigned int ArrayLength = SineLength+(SineLength/4u);
  constexpr double PI = 3.1415926535;
  
  float array[ArrayLength];
  
  void fillArray(unsigned int length)
  {
    for(unsigned int i = 0u; i &lt; length; ++i)
      array[i] = sin(double(i)*PI/180.*360./double(SineLength));
  }
  </code></pre>
  
  <p>As you can see, as far as the availability of information goes, this array <em>could</em> be declared <code>constexpr</code>.</p>
  
  <p>However, for the first approach linked, the generator function <code>f</code> would have to look like this:</p>
  
  <pre><code>constexpr float f(unsigned int i)
  {
    return sin(double(i)*PI/180.*360./double(SineLength));
  }
  </code></pre>
  
  <p>And that means that a template argument of type <code>float</code> is needed. Which is not allowed.</p>
  
  <p>Now, the first idea that springs to mind would be to store the float in an int variable - nothing happens to the array indices after their calculation, so pretending that they were of another type than they are (as long as byte-length is equal) is perfectly fine.</p>
  
  <p>But see:</p>
  
  <pre><code>constexpr int f(unsigned int i)
  {
    float output = sin(double(i)*PI/180.*360./double(SineLength));
    return *(int*)&amp;output;
  }
  </code></pre>
  
  <p>is not a valid <code>constexpr</code>, as it contains more than the return statement.</p>
  
  <pre><code>constexpr int f(unsigned int i)
  {
    return reinterpret_cast&lt;int&gt;(sin(double(i)*PI/180.*360./double(SineLength)));
  }
  </code></pre>
  
  <p>does not work either; even though one might think that <code>reinterpret_cast</code> does exactly what is needed here (namely nothing), it apparently only works on pointers.</p>
  
  <p>Following the second approach, the generator function would look slightly different:</p>
  
  <pre><code>template&lt;size_t index&gt; struct f
  {
    enum : float{ value = sin(double(index)*PI/180.*360./double(SineLength)) };
  };
  </code></pre>
  
  <p>With what is essentially the same problem: That enum cannot be of type <code>float</code> and the type cannot be masked as <code>int</code>.</p>
  
  <hr>
  
  <p>Now, even though I have only approached the problem on the path of "pretend the <code>float</code> is an <code>int</code>", I do not actually like that path (aside from it not working). I would much prefer a way that actually handled the <code>float</code> as <code>float</code> (and would just as well handle a <code>double</code> as <code>double</code>), but I see no way to get around the type restriction imposed.</p>
  
  <p>Sadly, there are many questions about this issue, which always refer to integral types, swamping the search for this specialised issue. Similarly, questions about masking one type as the other typically do not consider the restrictions of a <code>constexpr</code> or template parameter environment.<br>
  See <a href="https://stackoverflow.com/q/13313980">[1]</a><a href="https://stackoverflow.com/q/11509284">[2]</a><a href="https://stackoverflow.com/q/20436611">[3]</a> and <a href="https://stackoverflow.com/q/8365143/3434465">[4]</a><a href="https://stackoverflow.com/q/4149992/3434465">[5]</a> etc.</p>