如何约束模板化的 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>();
}

https://godbolt.org/g/KLgxdm

为什么会这样?还有其他方法可以在编译时检查参数吗?

这是因为 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>();
}