打包(类型擦除)随机数生成器 [英] pack (type erase) a random number generator

查看:117
本文介绍了打包(类型擦除)随机数生成器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++ 11 std库具有几个随机数生成器(RNG),每个实现概念本文档概述.

The C++11 std library has several random number generators (RNG), each implementing the concept UniformRandomNumberGenerator. These can then be used as argument for random distributions, see also this documentation for an overview.

这种设计的优势在于,底层RNG引擎的选择与其应用程序脱钩.但是,设计还要求对RNG的所有调用的定义(不仅是声明)可用(如果RNG类型保持未指定为模板参数的话).因此,在

The advantage of this design is that the choice of the underlying RNG engine is de-coupled from its application. However, the design also requires the definition (not merely the declarations) of all calls to the RNG to be available (if the RNG type is to remain unspecified as template parameter). Thus, in

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;
};

成员operator()不能在单独的编译单元(CU)中直接实现,但必须在同一头文件(或其中的一个#include d)中可用.

the member operator() cannot be straightforwardly implemented in a separate compilation unit (CU), but must be available in the same header file (or one #included from it).

对于单独的实现,理想情况下,您将需要某种方式来打包RNG,就像std::function<>打包任何可调用对象一样. (仅使用std::function并将RNG::min()RNG::max()的值用作在单独的CU中定义的函数的参数是限制性的,并且不允许在内部使用例如std::uniform_real_distribution<>).

For a separate implementation, one ideally would want some way to pack a RNG in the same way as std::function<> packs any callable object. (Simply using std::function and providing the values for RNG::min() and RNG::max() as arguments to a function defined in a separate CU is restrictive and will not allow to use, say, std::uniform_real_distribution<> inside).

这怎么办?有可用的实现方式吗?标准库会在将来提供吗?还是我在红鲱鱼之后?

How can this be done? Are implementations for this available? Will the std library provide this in the future? Or am I after a red herring?

Edit 随机数生成器必须具有static成员min()max(),从而很难或不可能进行类型擦除(GNU的libstdc ++并未进行此假设,也不进行类型擦除非静态成员min()max()可以使用,但不适用于LLVM的libc ++,后者使用必需的标准static成员).有没有办法解决这个问题?如果不是,这是否意味着C ++标准为随机数生成器提供了一个较差的接口?

Edit Random number generators are required to have static members min() and max(), making type-erasure hard or impossible (GNU's libstdc++ doesn't make this assumption and a type erasure with non-static members min() and max() works, but not with LLVM's libc++, which uses the standard required static members). Is there a way to still solve this problem? If not, doesn't this imply that the C++ standard has a botched interface for random number generators?

推荐答案

使用independent_bits_engine修改RNG,然后键入擦除修改后的RNG.您完全了解independent_bits_enginemin()max()是什么.

Adapt the RNG with an independent_bits_engine, and type erase the adapted RNG. You have full knowledge of what the independent_bits_engine's min() and max() are.

这是草图:

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;
};

这篇关于打包(类型擦除)随机数生成器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆