我们可以统一
GetRand
作为函数模板。
首先,请注意
std::uniform_real_distribution<T>
如果
T
不是其中之一
float
,
double
和
long double
.
例如,
29.6.1.1一般要求[rand.req.genl]
在C++标准草案n4687中规定:
贯穿本款
29.6
,实例化模板的效果:
...
d) 具有名为
实型
未定义,除非相应的模板
参数是cv不合格的,是其中之一
浮动
,
双重的
或
长双人
.
此外
29.6
.8.2.2类模板统一实分布[rand.dist.uni.real]描述
std::uniform_real_distribution
使用模板类型参数
RealType
因此
std::uniform_real_distribution<int>
未定义:
template<class RealType = double>
class uniform_real_distribution {
...
};
此外,对儿童也存在类似的限制
std::uniform_int_distribution<T>
.
因此,我们需要在
标准:均匀实分布<T>
和
标准:均匀分布<T>
取决于
T
.
我们可以使用
std::is_floating_point
和
std::is_integral
并进行以下切换:
#include <random>
#include <type_traits>
template<class T>
using uniform_distribution =
typename std::conditional<
std::is_floating_point<T>::value,
std::uniform_real_distribution<T>,
typename std::conditional<
std::is_integral<T>::value,
std::uniform_int_distribution<T>,
void
>::type
>::type;
然后是两个超负荷的
格特兰
可以统一到以下函数模板。
在这里,我还避免递归构造
std::mt19937_64
并使函数线程安全地应用已接受的答案
this post
.
template <class T>
T GetRand(T lower, T upper)
{
static thread_local std::mt19937_64 mt(std::random_device{}());
uniform_distribution<T> dist(lower,upper);
return dist(mt);
}
最后,调用方将如下所示:
DEMO
auto i = GetRand<int> (0, 1); // 0 or 1
auto f = GetRand<float> (0, 1); // [0, 1)
auto d = GetRand<double>(0, 1); // [0, 1)