将整数参数传递给接受浮点数的变量模板。

问题描述 投票:0回答:1

我正在尝试对 "广义β函数 "进行编码(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是隐式转换为浮点类型的。

在这些情况下,我怎样才能强制执行隐式转换为浮点型呢? 谢谢。

c++17 variadic-templates c++20 c++-concepts
1个回答
0
投票

(自答)一个变通的方法。

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. 寻找更好的解决方案...

(编辑): 解决了!是的!是的

© www.soinside.com 2019 - 2024. All rights reserved.