代码之家  ›  专栏  ›  技术社区  ›  Jakub Piskorz

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

  •  1
  • Jakub Piskorz  · 技术社区  · 6 年前

    我想检查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 回复  |  直到 6 年前
        1
  •  1
  •   llllllllll    6 年前

    这是因为 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>();
      }
    }
    
        2
  •  1
  •   Jive Dadson hmishra2250    6 年前

    根据定义,模板是一个无限递归。方法如下:

    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>();
    }