0

我正在尝试学习 C++11随机的东西,所以我从这个站点复制了一个示例,该站点在 stackoverflow 上找到...

我想在这里实现的是使用std::xor_combine模板来组合两个引擎并使用第三个引擎对其进行初始化。根据上面的链接,这应该是可能的,但是自从 Tr1 报告以来,这里似乎有些事情发生了变化?

此外,您将在代码中看到一个指数分布对象,所以还有一个问题是如何将xor_combine lobject 与分布结合起来,以便将“组合”传递给分布operator()

Visual Studio 给了我下面代码中描述的错误...

#include<iostream>
#include<random>
#include<ctime>
using namespace std;

int main()

{
    minstd_rand gen1;
    mt19937 gen2;
    linear_congruential_engine<unsigned long, 34999, 0, 3405989> seeder;

seeder.seed(static_cast<unsigned long>(time(false)));
xor_combine<minstd_rand, 4, mt19937, 9> combin;

exponential_distribution<float> expdist(2);

combin.seed(seeder);

// generate numbers
for(int i = 0; i < 10; ++i)     // error in <random> 
    cout << combin() << endl; // ERROR  C:2039 generate is not a member of std::congruential_engine<...> etc... 

cin.get();
    return 0;
}

1. 如何将第 3 个引擎传递给 xor_combine 对象?

2. 如何将 xor_combine 对象传递给分布对象? *编辑*

#include<iostream>
#include<random>
#include<ctime>
int main()
{
    std::minstd_rand gen1;
    std::mt19937 gen2;
    std::xor_combine<std::minstd_rand, 3, std::mt19937, 6> combin(gen1, gen2);
    std::uniform_int_distribution<unsigned int> dist(0,37);
    combin.seed(static_cast<unsigned int>(time(0)));
    std::cout << dist( combin ) << std::endl;
    std::cin.get();
    return 0;
}

错误 1 ​​错误 C2352: 'std::xor_combine<_Engine1,_S1,_Engine2,_S2>::max' : 非法调用非静态成员函数 c:\program files (x86)\microsoft visual studio 11.0\vc\include\ xutility 3455 项目1 1

4

1 回答 1

2

std::xor_combine在 C++11 中不存在。它已作为库缺陷报告 789的解决方案被删除。

没有争议。比尔是对的,但费米实验室认为这很容易用不好,很难用对,所以应该完全删除它。通过明确的路线进入 TR1,我们是否有权删除东西?可能应该与 Jens 核实一下,因为据信他是发起人。广泛的共识是这不是一个强大的引擎适配器。

MSDN 不是对真正标准的引用。请参阅在哪里可以找到当前的 C 或 C++ 标准文档?如何获得标准。


您的“生成不是成员”问题是因为

combin.seed(seeder);

这将有效地调用

combin.base1().seed(seeder); // ignoring the const-ref
combin.base2().seed(seeder);

在 TR1 中,随机数生成器可以由另一个随机数生成器播种(n1836 表 16)。但是,在 C++11 中,随机数生成器应改为“种子序列”(n3290 §26.5.1.2,不确定何时引入更改)。C++11 没有检查seeder调用中是 RNG 还是种子序列的概念,因此模板实例化将假定seeder是种子序列。“种子序列”的要求之一是要有一个.generate成员函数(n3290 表 115),这就是您遇到编译器错误的原因。

您可以尝试使用不了解“种子序列”概念的 TR1 引擎来解决此问题,或者您可以将 RNG 包装到输入迭代器中,然后包装到 astd::seed_seq中,或者只是带有数字的种子。

unsigned long seed = ....;
combin.seed(seed);

对于您的最后两个问题:

  1. 请注意,XOR 是关联的。这意味着,你可以只使用

    xor_combine<RNGa, sa, xor_combine<RNGb, sb, RNGc, sc>, 0>
    

    结合 3 个引擎

  2. xor_combine像所有其他 RNG 一样将对象传递给分布,例如

    std::uniform_int_distribution<> d(0, 10);
    std::cout << d(combin) << std::endl;
    
于 2012-04-29T08:29:16.277 回答