title: Do I need to put constexpr after else-if?
body: <p>Inspired by <a href="https://stackoverflow.com/a/52355930/7151494">this answer</a>, I tried to copy and paste (and add testing in <code>main()</code>) this code:</p>
  
  <pre><code>template&lt;typename T&gt;
  std::tuple&lt;int, double&gt; foo(T a) {
      if constexpr (std::is_same_v&lt;int, T&gt;)
          return {a, 0.0};
      else if (std::is_same_v&lt;double, T&gt;)
          return {0, a};
      else
          return {0, 0.0};
  }
  
  int main() {
      auto [x, y] = foo("");
      std::cout &lt;&lt; x &lt;&lt; " " &lt;&lt; y;
  }
  </code></pre>
  
  <p>This is very straightforward - if <code>T</code> is deduced as <code>int</code>, we want to return a tuple of <code>[a, 0.0]</code>. If <code>T</code> is deduced as <code>double</code>, we want to return a tuple of  <code>[0, a]</code>. Otherwise, we want to return <code>[0, 0.0]</code>.</p>
  
  <p>As you can see, in the <code>main()</code> function, I am calling <code>foo</code> with <code>const char*</code> argument, which <em>should</em> result in <code>x</code> and <code>y</code> being <code>0</code>. That is <em>not the case</em>.</p>
  
  <p>While trying to compile it, I encountered a strange error:</p>
  
  <blockquote>
    <p>error: could not convert '<code>{0, a}</code>' from '<code>&lt;brace-enclosed initializer list&gt;</code>' to '<code>std::tuple&lt;int, double&gt;</code>'</p>
  </blockquote>
  
  <p>And I was like <em>what?</em>. Why on earth would I want that... I specifically used <code>std::is_same</code> to enable <code>return {0, a}</code> <strong>only</strong> when the type of <code>a</code> is deduced as <code>double</code>.</p>
  
  <p>So I quickly ran to <a href="https://en.cppreference.com/w/cpp/language/if" rel="noreferrer">cppreference</a> on if-constexpr. At the bottom of the page, above <strong>Notes</strong>, we can see this snippet of code: </p>
  
  <pre><code>extern int x; // no definition of x required
  int f() {
  if constexpr (true)
      return 0;
  else if (x)
      return x;
  else
      return -x;
  }
  </code></pre>
  
  <p>I thought to myself <em>oookay..? I can't really see what's wrong with the original code. They use the same syntax and semantics...</em>.</p>
  
  <p>But I was curious. I was curious if maybe something odd (at that time) might fix that issue, so I changed the original code to:</p>
  
  <pre><code>template&lt;typename T&gt;
  std::tuple&lt;int, double&gt; foo(T a) {
      if constexpr (std::is_same_v&lt;int, T&gt;)
          return {a, 0.0};
      else if constexpr (std::is_same_v&lt;double, T&gt;) // notice the additional constexpr here
          return {0, a};
      else
          return {0, 0.0};
  }
  
  int main() {
      auto [x, y] = foo("");
      std::cout &lt;&lt; x &lt;&lt; " " &lt;&lt; y;
  }
  </code></pre>
  
  <p>And voilà! The code compiled and executed as expected. So, my question is - <strong>Do we need to put <code>constexpr</code> after every <code>if</code> statement in <code>if-else</code> statement in these kind of situations?</strong> Or is it just my compiler? I am using GCC 7.3.</p>