C++11 FAQ 中随机数生成器

来源:互联网 发布:天刀少女捏脸数据导入 编辑:程序博客网 时间:2024/06/18 10:42

头文件是<random>, 这个别忘记了。另外一般还会用到bind函数,用以简写,所以包括<functional>头文件也是必须的。


既然看不懂FAQ,那就直接抄大神的代码吧!

#include <iostream>#include <vector>#include <functional>#include <random>using namespace std;default_random_engine re;normal_distribution<<span style="color:#FF0000;">int</span>> nd(31, 8);auto norm = std::bind(nd, re);vector<int> mn(64);int main(){for(int i = 0; i < 1200; ++i) ++mn[round(norm())]; // generatefor(int i = 0; i < mn.size(); ++i){cout << i << '\t';for(int j = 0; j < mn[i]; ++j) cout << '*';cout <<'\n';}}

编译一下试试,咦,怎么有error?难道抄代码也抄错了么?


看看编译器报了啥错误:

/usr/include/c++/4.8/bits/random.h:2087:7: error: static assertion failed: template argument not a floating point type


还定位到normal_distribution<int> nd(31,8); 这一行上。看来是产生正态分布错了。查看一下正态分布的头文件,原来这个模板只能传递float类型的“类型”。呃,应该怎么表达才好呢?


比如,迭代器(iterator)分为input_iterator, output_iterator, forward_iterator, bidirectional_iterator和random_access_iterator五种。其中作用在前两种的算法都可以直接作用在后三种上,而后三种中,FI最弱,BDI次之,RAI最强。强概念(concept)包含弱概念,作用在弱概念的算法自然可以作用在强概念上,反之则不行(至少逻辑上不行)。


这篇博文当然不是讨论迭代器的问题。我们看看代码中是如何定义is_floating_point<_RealType>::value的:


template<class T >struct is_floating_point : std::integral_constant<                               bool,                               std::is_same<float, typename std::remove_cv<T>::type>::value  ||                               std::is_same<double, typename std::remove_cv<T>::type>::value  ||                               std::is_same<long double, typename std::remove_cv<T>::type>::value                           > {};

其中remove_cv是去掉类型的const和volatile属性(猿猿觉得称为修饰更合适)。当然,如果是指针也只是去掉指针本身的cv属性,不会改变指向内容的cv。这个不是重点,详细请参阅这里。


看看代码中的内容,就知道哪些是被is_floating_point 判断为true的类型(GP中称之为model)了:float(废话),double, 还有 long double。至少目前就这三种了。难怪刚才传进去int出现static assertion fail了。话说这种断言错误也是c++11才新有的东东哦!


把类型改称float会如何呢?(代码不附了,就是改了个模板参数)


哈哈,运行正确,猿猿好开心啊!看来大神们也是智者千虑,必有一失啊。只有代码才会告诉诸位猿猿们真相。


有关is_floating_point 的信息参见这里。


0 0
原创粉丝点击