如何约束模板化的 constexpr 递归函数输入参数
How to constrain templated constexpr recursive function input parameters
我想检查我的 constexpr 递归函数中的输入模板参数,但我发现它总是因评估整个变量范围而失败。
示例:
template<unsigned char t>
constexpr unsigned char test() {
static_assert(t < 20, "param check");
return t < 10 ? t : test<t-1>();
}
int main() {
return test<14>();
}
为什么会这样?还有其他方法可以在编译时检查参数吗?
这是因为 test<t>
的实例化总是需要 test<t-1>
的实例化,因此你有一个没有停止条件的无限递归。
您可以明确地特化停止标准:
template<unsigned char t>
constexpr unsigned char test() {
static_assert(t < 20, "param check");
return t < 10 ? t : test<t-1>();
}
template<>
constexpr unsigned char test<0>() {
return 0;
}
int main() {
return test<14>();
}
另一种方式是使用if constexpr
,那么对于不满足的条件,不会进行实例化:
template<unsigned char t>
constexpr unsigned char test() {
static_assert(t < 20, "param check");
if constexpr ( t < 10 ) {
return t;
} else {
return test<t-1>();
}
}
按照定义,模板是一个无限递归。方法如下:
template<unsigned char t>
constexpr unsigned char test() {
static_assert(t<20, "param check");
if constexpr (t < 10)
return t;
else return t - 1;
}
int main() {
return test<14>();
}
我想检查我的 constexpr 递归函数中的输入模板参数,但我发现它总是因评估整个变量范围而失败。
示例:
template<unsigned char t>
constexpr unsigned char test() {
static_assert(t < 20, "param check");
return t < 10 ? t : test<t-1>();
}
int main() {
return test<14>();
}
为什么会这样?还有其他方法可以在编译时检查参数吗?
这是因为 test<t>
的实例化总是需要 test<t-1>
的实例化,因此你有一个没有停止条件的无限递归。
您可以明确地特化停止标准:
template<unsigned char t>
constexpr unsigned char test() {
static_assert(t < 20, "param check");
return t < 10 ? t : test<t-1>();
}
template<>
constexpr unsigned char test<0>() {
return 0;
}
int main() {
return test<14>();
}
另一种方式是使用if constexpr
,那么对于不满足的条件,不会进行实例化:
template<unsigned char t>
constexpr unsigned char test() {
static_assert(t < 20, "param check");
if constexpr ( t < 10 ) {
return t;
} else {
return test<t-1>();
}
}
按照定义,模板是一个无限递归。方法如下:
template<unsigned char t>
constexpr unsigned char test() {
static_assert(t<20, "param check");
if constexpr (t < 10)
return t;
else return t - 1;
}
int main() {
return test<14>();
}