我已將我的一個專案從 VS 2019 轉換為 VS 2022,并且以下條件編譯模板不再正確編譯:
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";
}
}
這個想法是system_state根據特定模板編譯部分代碼,如下所示:
int main()
{
system_state<T_USER> user_state;
}
但現在if constexpr std::is_same似乎沒有檢測到我的T,我總是得到我的static_assert條款:
T 中的錯誤模板型別:必須是 T_USER 或 T_SERVICE
發生了什么變化?它曾經在 VS 2019 中作業。
uj5u.com熱心網友回復:
代碼格式錯誤,因為對于constexpr if:
注意:對于每個可能的專業化,被丟棄的陳述句不能是格式錯誤的:
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 }這種包羅萬象的陳述句的常見解決方法是依賴于型別的運算式,該運算式始終為假:
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 }
您也可以在分支中使用上面的型別相關運算式,例如else
//Bad type
static_assert(dependent_false_v<T>, "Bad template type in T: must be either T_USER or T_SERVICE");
順便說一句:在if constexpr (std::is_same<T, T_USER>),std::is_same<T, T_USER>是型別但不是bool值;您應該將其更改為std::is_same_v<T, T_USER>, 或std::is_same<T, T_USER>::value, 或std::is_same<T, T_USER>()( std::is_same<T, T_USER>{})。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/444773.html
