我们有uniform_int_distribution和uniform_real_distribution,难道不可能有一个包罗万象的uniform_distribution,当指定它的时候,它专门用于float/double和int/.?
发布于 2016-08-14 10:05:25
AFAIU,上面@ answer 877329和@revolver_ocelot的注释正确地解释了这一点,而另一个答案是完全错误的。
统一uniform_int和uniform_real的接口是错误的,不是因为它们的实现方式不同(这可以通过模板专门化来解决),而是因为接口的含义不同。
假设我们统一了接口(在另一个答案中使用了建议的变体),如下所示:
template <typename T>
using uniform_distribution =
typename std::conditional<
std::is_integral<T>::value,
std::uniform_int_distribution<T>,
std::uniform_real_distribution<T>
>::type;那么,如果我们定义uniform_distribution<some_type> u(0, 9),含义就大不相同:
some_type是整数,那么u将输出大约1/10倍的时间。some_type不是,那么u就永远不会输出9。下面的代码(其输出为true,然后是false)说明了这一点:
#include <random>
#include <iostream>
#include <type_traits>
template <typename T>
using uniform_distribution =
typename std::conditional<
std::is_integral<T>::value,
std::uniform_int_distribution<T>,
std::uniform_real_distribution<T>
>::type;
int main()
{
std::random_device rd;
std::mt19937 gen(rd());
{
uniform_distribution<int> u(0, 9);
bool over_found = false;
for(size_t i = 0; i < 99999; ++i)
over_found = over_found || u(gen) >= 9;
std::cout << std::boolalpha << over_found << std::endl;
}
{
uniform_distribution<float> u(0, 9);
bool over_found = false;
for(size_t i = 0; i < 99999; ++i)
over_found = over_found || u(gen) >= 9;
std::cout << std::boolalpha << over_found << std::endl;
}
}此代码说明使用该类编写泛型代码是危险的。例如,如果要编写一个泛型函数,计算子范围中结果的直方图:[0,1),[1,2],.,[8,9],则结果将不兼容。
正如@revolver_ocelot所指出的,标准库的[end) convention不能用于统一整数(因为不可能指定生成最大uint值的统一整数随机数生成器),这是一个例外的签名。
https://stackoverflow.com/questions/38940216
复制相似问题