C++11 标准库有几个随机数生成器 (RNG),每个都实现了 UniformRandomNumberGenerator 的概念.然后这些可以用作随机分布的参数,另见 this documentation概览。
这种设计的优点是底层RNG引擎的选择与其应用程序解耦。但是,该设计还要求对 RNG 的所有调用的定义(不仅仅是声明)都可用(如果要保持未指定 RNG 类型作为模板参数)。因此,在
struct complicated_random_distribution
{
/*
some data and auxiliary methods here
*/
// complicated; may call RNG::operator() many times
template<typename RNG>
some_type operator()(RNG&gen) const;
};
成员(member)operator()
不能直接在单独的编译单元 (CU) 中实现,但必须在同一个头文件中可用(或其中一个 #include
d)。
对于单独的实现,理想情况下需要某种方式以与 std::function<>
相同的方式打包 RNG打包任何可调用对象。
(仅使用 std::function
并提供 RNG::min()
和 RNG::max()
的值作为在单独 CU 中定义的函数的参数是有限制的,并且不允许在内部使用例如 std::uniform_real_distribution<>
。
如何做到这一点?是否有可用的实现? std 库将来会提供这个吗?还是我在追逐红鲱鱼?
编辑随机数生成器需要有static
成员(member) min()
和 max()
, 使类型删除变得困难或不可能(GNU 的 libstdc++ 没有做出这种假设,并且使用非静态成员 min()
和 max()
进行类型删除有效,但不适用于 LLVM 的 libc++,它使用所需的标准 static
成员)。有没有办法仍然解决这个问题?如果不是,这是否意味着 C++ 标准对随机数生成器有一个拙劣的接口(interface)?
最佳答案
使用 independent_bits_engine
调整 RNG,然后键入删除调整后的 RNG。您完全了解 independent_bits_engine
的 min()
和 max()
是什么。
这是一个草图:
struct RNG_wrapper {
using result_type = std::uint32_t;
static constexpr result_type min() { return 0; }
static constexpr result_type max() { return 0xFFFFFFFF; }
template<class RNG>
using my_engine_type = std::independent_bits_engine<RNG, 32, result_type>;
template<class RNG,
class = std::enable_if_t<!std::is_same<std::decay_t<RNG>, RNG_wrapper>{}>>
RNG_wrapper(RNG&& r)
: rng(my_engine_type<std::decay_t<RNG>>(std::forward<RNG>(r))) {}
result_type operator()() { return rng(); }
std::function<result_type()> rng;
};
关于c++ - 打包(类型删除)随机数生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30571141/