如果没有 if-constexpr 成功,触发编译时错误的最佳方法?
Best way to trigger a compile-time error if no if-constexpr's succeed?
我有一长串 if constexpr
语句,如果 none 语句成功,我想触发一个编译时错误。
具体来说,我有一个抽象语法树,我想将其结果转换为我可能需要的一组特定类型。我有 AsInt()、AsDouble() 等在工作,但我需要能够根据提供的类型更动态地执行此操作。
就目前而言,我已经编写了一个模板化的 As() 成员函数,但它的错误检查很笨拙。具体来说,使用静态断言需要一个笨重的测试条件。这是一个简化版本:
template <typename T>
T As() {
if constexpr (std::is_same_v<T,int>) return AsInt();
if constexpr (std::is_same_v<T,double>) return AsDouble();
...
if constexpr (std::is_same_v<T,std::string>) return AsString();
static_assert( std::is_same_v<T,int>
|| std::is_same_v<T,double>
|| ...
|| std::is_same_v<T,std::string>,
"Invalid template type for As()" );
}
如果所有条件都失败,是否有更简单的方法来触发静态断言(或等效方法)?
您需要将 if constexpr
序列重写为 if constexpr ... else if constexpr ...
链,并让最后的 else
子句在“达到”(即未丢弃)时触发编译错误).这可以使用“dependent false
idiom”来完成:
if constexpr (std::is_same_v<T,int>) {
return AsInt();
} else if constexpr (std::is_same_v<T,double>) {
return AsDouble();
} ... else if constexpr (std::is_same_v<T,std::string>) {
return AsString();
} else {
// this is still constexpr, so it will be discarded if any other branch was taken
static_assert(dependent_false<T>::value, "invalid template type for As()");
}
其中 dependent_false
定义为:
template <class T> struct dependent_false : std::false_type {};
我有一长串 if constexpr
语句,如果 none 语句成功,我想触发一个编译时错误。
具体来说,我有一个抽象语法树,我想将其结果转换为我可能需要的一组特定类型。我有 AsInt()、AsDouble() 等在工作,但我需要能够根据提供的类型更动态地执行此操作。
就目前而言,我已经编写了一个模板化的 As() 成员函数,但它的错误检查很笨拙。具体来说,使用静态断言需要一个笨重的测试条件。这是一个简化版本:
template <typename T>
T As() {
if constexpr (std::is_same_v<T,int>) return AsInt();
if constexpr (std::is_same_v<T,double>) return AsDouble();
...
if constexpr (std::is_same_v<T,std::string>) return AsString();
static_assert( std::is_same_v<T,int>
|| std::is_same_v<T,double>
|| ...
|| std::is_same_v<T,std::string>,
"Invalid template type for As()" );
}
如果所有条件都失败,是否有更简单的方法来触发静态断言(或等效方法)?
您需要将 if constexpr
序列重写为 if constexpr ... else if constexpr ...
链,并让最后的 else
子句在“达到”(即未丢弃)时触发编译错误).这可以使用“dependent false
idiom”来完成:
if constexpr (std::is_same_v<T,int>) {
return AsInt();
} else if constexpr (std::is_same_v<T,double>) {
return AsDouble();
} ... else if constexpr (std::is_same_v<T,std::string>) {
return AsString();
} else {
// this is still constexpr, so it will be discarded if any other branch was taken
static_assert(dependent_false<T>::value, "invalid template type for As()");
}
其中 dependent_false
定义为:
template <class T> struct dependent_false : std::false_type {};