我正在尝试对 "广义β函数 "进行编码(https:/en.wikipedia.orgwikiBeta_function#Multivariate_beta_function。)的C++语言。
这是我的工作。
template <typename... Args>
constexpr auto sum(Args&&... args) {
return (args + ...);
}
// Beta(a1, a2, ..., an) = Beta(a1, a2 + ... + an) * Beta(a2, ..., an)
template <std::floating_point F, typename... Ts>
constexpr F multivariate_beta(F a1, Ts... args) {
static_assert(sizeof...(args) > 0);
F value = std::beta(a1, sum(args...));
if constexpr (sizeof...(args) == 1)
return value;
else
return value * multivariate_beta(args...);
}
这个函数在以下测试用例中工作得很好。
std::cout << multivariate_beta(1.0, 1.0, 1.0, 1.0) << '\n'; // should output 1 / 3!
std::cout << multivariate_beta(2.0, 3.0, 4.0) << '\n'; // should output 2! * 3! / 8!
但在以下测试用例中却失败了
std::cout << multivariate_beta(1, 1, 1, 1) << '\n'; // compile error
std::cout << multivariate_beta(2, 3, 4) << '\n'; // compile error
编译器抱怨说这个函数只接受... std::floating_point
我对这一点不满意,因为1, 1, 1, 1, 1和2, 3, 4是隐式转换为浮点类型的。
在这些情况下,我怎样才能强制执行隐式转换为浮点型呢? 谢谢。
(自答)一个变通的方法。
template <typename A>
concept Arithmetic = std::is_arithmetic_v<A>;
template <typename... Args>
constexpr auto sum(Args&&... args) {
return (args + ...);
}
// Beta(a1, a2, ..., an) = Beta(a1, a2 + ... + an) * Beta(a2, ..., an)
template <std::floating_point F = double, Arithmetic A, typename... Ts>
constexpr F multivariate_beta(A a1, Ts... args) {
static_assert(sizeof...(args) > 0);
F value = std::beta(a1, sum(args...));
if constexpr (sizeof...(args) == 1)
return value;
else
return value * multivariate_beta(args...);
}
坏处是返回值的类型没有被参数化,只是被强行设置为 double
. 寻找更好的解决方案...
(编辑): 解决了!是的!是的