您正在接近您的编辑。您需要将“积分”版本限制为积分类型。这将消除歧义:
template<typename T>
typename std::enable_if
<
std::is_integral<T>::value,
T
>::type
randomPrimitive()
但是如果你现在用这样的东西运行它:
#include <iostream>
int
main()
{
for (int i = 0; i < 10; ++i)
std::cout << randomPrimitive<float>() << '\n';
for (int i = 0; i < 10; ++i)
std::cout << randomPrimitive<double>() << '\n';
for (int i = 0; i < 10; ++i)
std::cout << (int)randomPrimitive<signed char>() << '\n';
for (int i = 0; i < 10; ++i)
std::cout << randomPrimitive<unsigned>() << '\n';
for (int i = 0; i < 10; ++i)
std::cout << randomPrimitive<bool>() << '\n';
}
你会得到类似的东西:
0.814724
0.814724
0.814724
0.814724
0.814724
0.814724
0.814724
0.814724
0.814724
0.814724
0.135477
0.135477
0.135477
0.135477
0.135477
0.135477
0.135477
0.135477
0.135477
0.135477
92
92
92
92
92
92
92
92
92
92
3499211612
3499211612
3499211612
3499211612
3499211612
3499211612
3499211612
3499211612
3499211612
3499211612
1
1
1
1
1
1
1
1
1
1
到达那里,但不是完全随机的。问题是您每次使用它时都在构建一个新引擎。您想要的是创建一个 URNG 一次,然后不断从中获取随机位:
std::mt19937&
get_eng()
{
static std::mt19937 eng;
return eng;
}
而且你真的应该只创建一次你的发行版。他们中的大多数是无国籍的,但不是全部。最好只是假设它们都带有状态,并且您不想丢弃该状态。
static std::uniform_real_distribution<T> dst;
这将大大改善事情,但你还没有:
0.814724
0.135477
0.905792
0.835009
0.126987
0.968868
0.913376
0.221034
0.632359
0.308167
0.547221
0.188382
0.992881
0.996461
0.967695
0.725839
0.98111
0.109862
0.798106
0.297029
92
13
49
122
46
7
105
45
43
8
2816384844
3427077306
153380495
1551745920
3646982597
910208076
4011470445
2926416934
2915145307
1712568902
0
1
1
1
1
0
1
0
1
0
我注意到所有 10 个值signed char
都是正的。那看起来不对。事实证明,它std::uniform_int_distribution
有一个如下所示的构造函数:
explicit uniform_int_distribution(IntType a = 0,
IntType b = numeric_limits<IntType>::max());
我猜这不是你想要的,所以:
static std::uniform_int_distribution<T> dst(std::numeric_limits<T>::min(),
std::numeric_limits<T>::max());
最后,如果您想要一个随机的bool
,请使用std::bernoulli_distribution
.
把这一切放在一起:
#include <random>
std::mt19937&
get_eng()
{
static std::mt19937 eng;
return eng;
}
template<typename T>
typename std::enable_if
<
std::is_integral<T>::value,
T
>::type
randomPrimitive()
{
static std::uniform_int_distribution<T> dst(std::numeric_limits<T>::min(),
std::numeric_limits<T>::max());
return dst(get_eng());
}
template<>
bool
randomPrimitive<bool>()
{
static std::bernoulli_distribution dst;
return dst(get_eng());
}
template<typename T>
typename std::enable_if
<
std::is_floating_point<T>::value,
T
>::type
randomPrimitive()
{
static std::uniform_real_distribution<T> dst;
return dst(get_eng());
}
#include <iostream>
int
main()
{
for (int i = 0; i < 10; ++i)
std::cout << randomPrimitive<float>() << '\n';
for (int i = 0; i < 10; ++i)
std::cout << randomPrimitive<double>() << '\n';
for (int i = 0; i < 10; ++i)
std::cout << (int)randomPrimitive<signed char>() << '\n';
for (int i = 0; i < 10; ++i)
std::cout << randomPrimitive<unsigned>() << '\n';
for (int i = 0; i < 10; ++i)
std::cout << randomPrimitive<bool>() << '\n';
}
对我来说输出:
0.814724
0.135477
0.905792
0.835009
0.126987
0.968868
0.913376
0.221034
0.632359
0.308167
0.547221
0.188382
0.992881
0.996461
0.967695
0.725839
0.98111
0.109862
0.798106
0.297029
92
13
-79
-6
46
-121
-23
45
43
8
2816384844
3427077306
153380495
1551745920
3646982597
910208076
4011470445
2926416934
2915145307
1712568902
0
1
1
1
1
0
1
0
1
0
如果这仍然没有输出你想要的,希望你有足够的方向从这里开始。