如何创建没有特定定义的随机分布?uniform_int_distribution是从其他类继承的吗?
How to create a random distribution with no specific definition? Is uniform_int_distribution inheriting from other class?
我想创建一段使用名为Number
的代码,该类型可以是浮点数或任何整数(例如uint64_t
(。我有一个变量dist
,即应该用于生成随机数的分布,但在任何这些情况下都应该不同,所以我想做这样的事情:
constexpr bool number_is_floating = std::is_floating_point<Number>::value;
#if number_is_floating
std::uniform_real_distribution<Number> dist(1.0, 1000.0);
#else
std::uniform_int_distribution<Number> dist(1, 1000);
#endif
但这当然是行不通的,因为预处理器变量在常量number_is_floating
之前被计算,所以这个表达式总是假的。我实际上尝试这样做:
Number getran() {
if constexpr (number_is_floating)
return std::uniform_real_distribution<Number>(1.0, 1000.0)(eng);
else
return std::uniform_int_distribution<Number>(1, 1000)(eng);
}
但这不起作用,因为我们正在尝试编译使用可能是也可能不是整数的类型(对于实际分布也是如此(初始化uniform_int_distribution
的代码。
使此代码工作的最佳和最优雅的方法是什么,即使Number
浮点数或不是浮点数?
但这不起作用,因为我们正在尝试编译以整数或可能不是整数的类型启动uniform_int_distribution的代码(对于实际分布也是如此(。
不,if constexpr
在编译时计算,并且只编译其中一个分支,另一个被丢弃,例如未编译。像这样的东西编译并按(可能(预期工作:
#include <random>
#include <iostream>
#include <type_traits>
template<typename TNumber>
TNumber getran() {
static std::default_random_engine eng; // Just to avoid undefined variables
if constexpr (std::is_floating_point<TNumber>::value)
return std::uniform_real_distribution<TNumber>(1.0, 1000.0)(eng);
else
return std::uniform_int_distribution<TNumber>(1, 1000)(eng);
}
int main()
{
std::cout << getran<float>() << ", "
<< getran<int>() << ", "
<< getran<double>() << ", "
<< getran<unsigned>();
}
Number getran_internal(std::integral_constant<bool, true> is_floating) {
return std::uniform_real_distribution<Number>(1.0, 1000.0)(eng);
}
Number getran_internal(std::integral_constant<bool, false> is_floating) {
return std::uniform_int_distribution<Number>(1, 1000)(eng);
}
Number getran() {
return getran_internal( std::integral_constant<bool, number_is_floating>{} );
}
一种方式,多种方式。
哪种方式是理想的,取决于您的编译器对各种 C++11 及以上功能的支持。 这个应该适用于任何 C++11 编译器。
我会声明一个模板函数,并在为每个特定类型实现它时使用相应的发行版。
typedef std::default_random_engine generator;
typedef float Number;
template <typename T>
T next_random_number(generator &g);
template<>
float next_random_number<float>(generator &g) {
std::uniform_real_distribution<float> dist(1.0, 1000.0);
return dist(g);
}
template<>
int next_random_number<int>(generator &g) {
std::uniform_int_distribution<int> dist(1, 1000);
return dist(g);
}
Number next(generator &g) {
return next_random_number<Number>(g);
}
int main() {
std::random_device r;
generator g(r());
for(int i = 0; i < 10; i++)
std::cout << next(g) << std::endl;
return 0;
}
希望我正确理解你的问题。
相关文章:
- 为什么在全局范围内使用"extern int a"似乎不行?
- int(c) 和 c-'0' 之间的区别。C++
- 从"int*"强制转换为"unsigned int"会丢失精度错误
- 为什么野牛仍在使用"int yylex(void)",却找不到"int yylex(YYS
- 有符号的int和int-有没有一种方法可以在C++中区分它们
- 请解释这句话(cout<<1+int((a<b)^((b-a)&1) )<<endl
- 是否可以从int转换为enum类类型
- 不能在初始值设定项列表中将非常量表达式从类型 'int' 缩小到'unsigned long long'
- 向量 <int> a {N, 0} 和 int arr a[N] = {0} 的时间复杂度有什么区别
- 'short int'持有的值溢出,但"自动"不会溢出?
- 如何在C++中将一个无符号的 int 转换为两个无符号的短裤?
- 调用'begin(int [n])'没有匹配函数
- 没有显式声明的int[]中的foreach
- 在c++中访问int到类对象的映射时出错
- 为什么我无法更改"set<set>"循环中的值<int>
- 长 长 int 不要 长 int 好
- C++程序在循环后给出奇怪的int值
- 如何计算数据类型的范围,例如int
- 如果"new int"返回"int*",那么为什么"new int[n]"不返回"int**"?
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)