c++ - 如何约束模板化 constexpr 递归函数输入参数

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

当我发现 constexpr 递归函数由于评估整个变量范围而始终失败时,我想检查 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>();
  }
}

关于c++ - 如何约束模板化 constexpr 递归函数输入参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49213507/

相关文章:

c++ - 将 typedef 移动到函数模板参数时编译错误

java - 从 Java 对象类到 C++

c++ - CRTP 容器

ruby - 尝试通过 Ruby 创建我自己的结构

c++ - std::is_same 无法通过 constexpr 自动变量的 decltype 工作

C++ std::map::iterator 什么也没找到,但下标运算符返回对映射值的引用?

c++ - 如何将 Windows 窗体应用程序 (C++) 设置为具有 Aero/Glass 背景?

c++ - SDL_surface 到 OpenGL 纹理

C++ 模板数组类 : Error generation depends on whether it inherits an interface or not

java - 无法声明注释数组