gpt4 book ai didi

c++ - 由于意外的模板参数类型推导而导致的无限递归

转载 作者:行者123 更新时间:2023-12-02 10:18:09 25 4
gpt4 key购买 nike

请考虑以下类似boost::math::pdf的通用概率密度函数评估实现:

template<typename T, class Distribution>
inline typename Distribution::result_type pdf(Distribution const& d, T const& x) {
return pdf(d, static_cast<typename Distribution::result_type>(x));
}

template<typename RealType>
RealType pdf(std::uniform_real_distribution<RealType> const& d, RealType const& x)
{
if (d.a() <= x && x <= d.b())
return 1 / (d.b() - d.a());
return 0;
}

我想定义另一个 pdf函数,该函数需要一个分布和一个 vector ,并评估每个 vector 分量的概率密度。该函数也应该可用于嵌套 vector 。我已经尝试过这样的事情:
template<typename T, class Distribution>
inline typename Distribution::result_type pdf(Distribution const& d, std::vector<T> const& x)
{
return std::reduce(x.begin(), x.end(), typename Distribution::result_type{ 1 },
[&](auto const& p, auto const& x) { return p * pdf(d, x); });
}

示例代码:
std::vector<std::vector<double>> x = { {1}, {2, 3}, {4} };
std::vector<double> y = { 1, 2, 3, 4 };
std::uniform_real_distribution<> d;
std::cout << pdf(d, x) << std::endl;
std::cout << pdf(d, y) << std::endl;

这可以正常工作。但是,如果我将 std::uniform_real_distribution<> d;更改为 std::uniform_real_distribution<float> d;,那么对于 pdf(d, x)的调用,我最终将进行无限递归(出于明显的原因)。那么,我该如何更改代码?也许它也适用于其他容器。

最佳答案

而不是在第一种情况下有两个重载(基本上做同样的事情):

template<typename T, class Distribution>
inline typename Distribution::result_type pdf(Distribution const& d, T const& x) {
return pdf(d, static_cast<typename Distribution::result_type>(x));
}

template<typename RealType>
RealType pdf(std::uniform_real_distribution<RealType> const& d, RealType const& x)
{
if (d.a() <= x && x <= d.b())
return 1 / (d.b() - d.a());
return 0;
}

将它们折叠成一个:
template <typename R, typename T, std::enable_if_t<std::is_convertible_v<T, R>, int> = 0>
auto pdf(std::uniform_real_distribution<R> const& d, T x) -> R
{
if (d.a() <= x && x <= d.b()) {
return 1 / (d.b() - d.a());
}
return 0;
}

或更简单地是完全在第二个参数上阻止类型推导( std::type_identity是C++ 20,但实现起来很简单):
template <typename R>
auto pdf(std::uniform_real_distribution<R> const& d, std::type_identity_t<R> x) -> R

关于c++ - 由于意外的模板参数类型推导而导致的无限递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61254421/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com