if constexpr std::is_same 在 VS 2022 下
if constexpr std::is_same under VS 2022
我已将我的一个项目从 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
子句:
Bad template type in T: must be either T_USER or T_SERVICE
发生了什么变化?它曾经在 VS 2019 中工作。
代码是 ill-formed 因为 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
}
您也可以在 else
分支中使用上面的 type-dependent 表达式 ,例如
//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>{}
)。
我已将我的一个项目从 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
子句:
Bad template type in T: must be either T_USER or T_SERVICE
发生了什么变化?它曾经在 VS 2019 中工作。
代码是 ill-formed 因为 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 }
您也可以在 else
分支中使用上面的 type-dependent 表达式 ,例如
//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>{}
)。