Inconsistent behaviour across compilers in regard to instantiation of a template in a discarded if constexpr(false) statement
Definitively a bug of MSVC. A bug report exist and has been reportedly fixed in Visual Studio 2019 Preview.
if constexpr
is standardized in [stmt.if]/2
:
If the
if
statement is of the formif constexpr
, the value of the condition shall be a contextually converted constant expression of type bool; this form is called a constexpr if statement.
This applies.
If the value of the converted condition is false, the first substatement is a discarded statement, otherwise [...].
It also applies, making in your program { std::optional<T> val; }
a discarded statement.
During the instantiation of an enclosing templated entity (ndYSC
Bar<void, int>
), if the condition is not value-dependent after its instantiation, the discarded substatement (if any) is not instantiated.
Along with @YSC's answer, also relevant is [temp.inst]/10
:
An implementation shall not implicitly instantiate a function template, a variable template, a member template, a non-virtual member function, a member class, a static data member of a class template, or a substatement of a constexpr if statement , unless such instantiation is required.