static_assert 使用 C++20 概念进行编译时参数检查
static_assert compile-time argument check with C++20 concept
我正在编写一个计算二项式系数的函数: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,但是编译器看起来不太高兴。
哦,当我尝试在 binom_pdf
中插入 static_assert(theta >= 0.0 && theta <= 1.0);
时,编译器也在抱怨。
我该怎么办?提前致谢。
函数参数不是constexpr
。
template <Unsigned U, U N, U K>
constexpr double binom()
会让你的 static_assert
.
如果您真的对所有这些仅适用于常量表达式感到满意,请在您不喜欢这些参数时声明函数 consteval
和 throw
(无需实际例外)。这允许浮点类型,即使没有编译器支持它们作为模板参数。
我正在编写一个计算二项式系数的函数: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,但是编译器看起来不太高兴。
哦,当我尝试在 binom_pdf
中插入 static_assert(theta >= 0.0 && theta <= 1.0);
时,编译器也在抱怨。
我该怎么办?提前致谢。
函数参数不是constexpr
。
template <Unsigned U, U N, U K>
constexpr double binom()
会让你的 static_assert
.
如果您真的对所有这些仅适用于常量表达式感到满意,请在您不喜欢这些参数时声明函数 consteval
和 throw
(无需实际例外)。这允许浮点类型,即使没有编译器支持它们作为模板参数。