首页 > 解决方案 > 使用 C++20 概念的 static_assert 编译时参数检查

问题描述

我正在编写一个评估二项式系数的函数:binom(N, K)

我想在编译时检查 N 和 K 是否都是 N >= K 的无符号整数,但是有这个问题。

这是我的代码:

template <typename N>
concept Unsigned = std::is_unsigned_v<N>;

template <Unsigned U>
constexpr double binom(U N, U K) {
    static_assert(N >= K);
    double d = 1.0;
    while (K) {
        d *= static_cast<double>(N) / static_cast<double>(K);
        K--;
        N--;
    }
    return d;
}

template <Unsigned U>
constexpr double binom_pmf(U N, U K, double theta) {
    return binom(N, K) * std::pow(theta, K) * std::pow(1 - theta, N - K);
}

这是来自 Clang 10 的错误消息:


/mnt/c/programming/ML/2_3_1_binomial_bernoulli.cpp:12:19: error: static_assert expression is not an integral constant expression
    static_assert(N >= K);
                  ^~~~~~
/mnt/c/programming/ML/2_3_1_binomial_bernoulli.cpp:24:12: note: in instantiation of function template specialization 'binom<unsigned long>' requested here
    return binom(N, K) * std::pow(theta, K) * std::pow(1 - theta, N - K);
           ^
/mnt/c/programming/ML/2_3_1_binomial_bernoulli.cpp:36:16: note: in instantiation of function template specialization 'binom_pmf<unsigned long>' requested here
        y[K] = binom_pmf(N, K, theta);

问题是static_assert(N >= K)

我将参数 N 声明为constexpr size_t,而 K 是 中的循环参数for (size_t K = 0; K <= N; K++),因此任何人都可以得出结论,N 和 K 肯定是 N >= K 的无符号整数,但编译器看起来并不那么高兴。

哦,当我尝试插入static_assert(theta >= 0.0 && theta <= 1.0);.binom_pdf

我该怎么办?提前致谢。

标签: c++constexprc++20static-assert

解决方案


函数参数不是constexpr

template <Unsigned U, U N, U K> constexpr double binom()将允许您的static_assert.


推荐阅读