我正在尝试制作一个函数,用随机数填充列表,并根据列表项的类型生成整数或 float 。到目前为止,我已经提出了以下代码,并且它有效:
template <typename T>
void generateRandom(list<T>& numberList){
default_random_engine randomGenerator(random_device{}());
if( typeid(T) == typeid(int) ){
uniform_int_distribution<T> distribution(1000, 2000);
auto myGenerator = bind(distribution, randomGenerator);
generate(numberList.begin(), numberList.end(), myGenerator);
}
else if( typeid(T) == typeid(double) ){
uniform_real_distribution<T> distribution(1000.0, 2000.0);
auto myGenerator = bind(distribution, randomGenerator);
generate(numberList.begin(), numberList.end(), myGenerator);
}
else{
return;
}
}
但是,我对这个解决方案并不十分满意。感觉应该有某种方法可以分解除 IF 语句中的实际分布之外的所有内容。像这样的东西:
template <typename T>
void generateRandom(list<T>& numberList){
default_random_engine randomGenerator(random_device{}());
X distribution;
if( typeid(T) == typeid(int) )
distribution = uniform_int_distribution<T>(1000, 2000);
else if( typeid(T) == typeid(double) )
distribution = uniform_real_distribution<T>(1000.0, 2000.0);
else
return;
auto myGenerator = bind(distribution, randomGenerator);
generate(numberList.begin(), numberList.end(), myGenerator);
}
(X 是这里缺少的占位符)
但是自uniform_int_distribution
和 uniform_real_distribution
没有共同的基类,那怎么可能?我试过使用函数指针和仿函数,但我似乎从来没有绕过 IF 语句,这很烦人。这可以用更优雅的方式解决吗?
注意:这是学校作业的一部分,我们必须使用 generate()
和 <random>
生成随机数的函数和模板。我认为我原来的解决方案是可以接受的,我只是不喜欢 IF 语句中那些重复代码行的外观...:)
最佳答案
您可以创建类似类型特征的类:
template<class T>
struct Distribution {};
template<>
struct Distribution<int> {
typedef uniform_int_distribution<int> type;
};
template<>
struct Distribution<double> {
typedef uniform_real_distribution<double> type;
};
template <typename T>
void generateRandom(list<T>& numberList){
default_random_engine randomGenerator(random_device{}());
typename Distribution<T>::type distribution = typename Distribution<T>::type(1000, 2000);
...
另一种选择是创建一个模板辅助函数,它将接受所需的分布作为参数:
template<class T, template<class> class Distr>
void generateRandomHelper(list<T>& numberList){
default_random_engine randomGenerator(random_device{}());
Distr<T> distribution = Distr<T>(1000, 2000);
auto myGenerator = bind(distribution, randomGenerator);
generate(numberList.begin(), numberList.end(), myGenerator);
}
template<class T>
void generateRandom2(list<T>& numberList);
template<>
void generateRandom2<int>(list<int>& numberList) {
generateRandomHelper<int, uniform_int_distribution>(numberList);
}
template<>
void generateRandom2<double>(list<double>& numberList) {
generateRandomHelper<double, uniform_real_distribution>(numberList);
}
关于c++ - int 和 double 的均匀随机分布 "base class"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32907254/