I have converted one of my projects from VS 2019 to VS 2022 and the following conditional compilation template doesn't compile properly anymore:
struct T_USER;
struct T_SERVICE;
template<typename T>
class system_state
{
public:
system_state();
};
template<typename T>
system_state<T>::system_state()
{
if constexpr (std::is_same<T, T_USER>)
{
std::cout << "User templ\n";
}
else if constexpr (std::is_same<T, T_SERVICE>)
{
std::cout << "Service templ\n";
}
else
{
//Bad type
static_assert(false, "Bad template type in T: must be either T_USER or T_SERVICE");
std::cout << "Unknown templ\n";
}
}
The idea was to compile parts of code in system_state depending on a specific template, as such:
int main()
{
system_state<T_USER> user_state;
}
But now the if constexpr std::is_same doesn't seem to detect my T and I'm always getting my static_assert clause:
Bad template type in T: must be either T_USER or T_SERVICE
What has changed? It used to work in VS 2019.
The code is ill-formed because for constexpr if:
Note: the discarded statement can't be ill-formed for every possible specialization:
template <typename T> void f() { if constexpr (std::is_arithmetic_v<T>) // ... else static_assert(false, "Must be arithmetic"); // ill-formed: invalid for every T }The common workaround for such a catch-all statement is a type-dependent expression that is always false:
template<class> inline constexpr bool dependent_false_v = false; template <typename T> void f() { if constexpr (std::is_arithmetic_v<T>) // ... else static_assert(dependent_false_v<T>, "Must be arithmetic"); // ok }
You can use the type-dependent expression above in the else branch too, e.g.
//Bad type
static_assert(dependent_false_v<T>, "Bad template type in T: must be either T_USER or T_SERVICE");
BTW: In if constexpr (std::is_same<T, T_USER>), std::is_same<T, T_USER> is type but not a bool value; you should change it to std::is_same_v<T, T_USER>, or std::is_same<T, T_USER>::value, or std::is_same<T, T_USER>() (std::is_same<T, T_USER>{}).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With