如何约束模板化的constexpr递归函数输入参数

时间:2018-03-10 20:06:06

标签: c++ templates metaprogramming instantiation c++17

当我发现由于评估整个变量范围而总是失败时,我想在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

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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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>();
}