title: Inconsistent behaviour across compilers in regard to instantiation of a template in a discarded if constexpr(false) statement
body: <p>I am trying to understand whether the snippet below should compile according to The Standard or not. When I try to compile it with latest version of three major compilers, the following occurs:</p>
  
  <ul>
  <li><strong>✓</strong> Clang (version 7.0.0, with <code>-std=c++17</code> flag): compiles fine;</li>
  <li><strong>✓</strong> GCC (version 8.2, with <code>-std=c++17</code> flag): also compiles fine;</li>
  <li><strong>❌</strong> MSVC (version 19.16, with <code>/std:c++17</code> flag): compiler error (see below).</li>
  </ul>
  
  <p>The error occurs because the MSVC compiler seemingly tries to instantiate <code>std::optional&lt;void&gt;</code> despite the fact that the code is discarded. GCC and Clang don't seem to do that.</p>
  
  <p><strong>Does The Standard clearly define what should occur in this case?</strong></p>
  
  <pre><code>#include &lt;optional&gt;  
  #include &lt;type_traits&gt;
  template&lt;typename T, typename... Args&gt;
  struct Bar
  {
    void foo(Args... args)
    {
      if constexpr(!std::is_same_v&lt;T, void&gt;) // false
      {
        // MSVC compiler error occurs because of the line below; no error occurs when compiling with GCC and Clang 
        std::optional&lt;T&gt; val; 
      }
    }
  };
  int main(int argc, char** argv)
  {
    Bar&lt;void, int&gt; inst;
    inst.foo(1);
    return 0;
  }
  </code></pre>
  
  <p>Error by MSVC:</p>
  
  <blockquote>
  <pre><code>C:/msvc/v19_16/include\optional(87): error C2182: '_Value': illegal use of type 'void'
  
  C:/msvc/v19_16/include\optional(128): note: see reference to class template instantiation 'std::_Optional_destruct_base&lt;_Ty,false&gt;' being compiled
    with
    [
         _Ty=void
    ]
  </code></pre>
  </blockquote>
  
  <p><a href="http://godbolt.org/z/kDtgXp" rel="noreferrer">Live demo</a></p>