c++ - 生成每种类型的从最小值到最大值的随机值的模板函数
问题描述
我需要编写获取类型的函数模板,例如。int,然后生成从 MIN_INT 到 MAX_INT 的随机值
template<typename TYPE>
TYPE generateRandom()
{
srand(static_cast<unsigned int>(time(nullptr)));
TYPE generatedValue;
//code :/
return generatedValue;
}
这里有几个问题:
rand
生成 to0 小值 (RAND_MAX
)- 在
rand
我不能做INT_MAX+1
包括 int max 和负值
我也尝试过这样的事情:
std::random_device randomDevice;
std::mt19937_64 generator(randomDevice());
if(std::numeric_limits<TYPE>::is_integer)
{
std::uniform_int_distribution<TYPE> dice(std::numeric_limits<TYPE>::min(),std::numeric_limits<TYPE>::max());
generatedValue=dice(generator);
}
else
{
std::uniform_real_distribution<TYPE> dice(std::numeric_limits<TYPE>::min(),std::numeric_limits<TYPE>::max());
generatedValue=dice(generator);
}
但它没有用:/
解决方案
您的问题是您有一个if/else
分支,就像您将用于运行时值检查一样。您需要使用模板元编程技术进行编译时分支。
类似于以下内容的东西应该可以工作。
template <typename TYPE>
std::uniform_int_distribution<TYPE> getDice(std::true_type)
{
return std::uniform_int_distribution<TYPE>(std::numeric_limits<TYPE>::min(), std::numeric_limits<TYPE>::max());
}
template <typename TYPE>
std::uniform_real_distribution<TYPE> getDice(std::false_type)
{
return std::uniform_real_distribution<TYPE>(std::numeric_limits<TYPE>::min(), std::numeric_limits<TYPE>::max());
}
template<typename TYPE>
TYPE generateRandom()
{
std::random_device randomDevice;
std::mt19937_64 generator(randomDevice());
auto dice = getDice<TYPE>(std::integral_constant<bool, std::numeric_limits<TYPE>::is_integer>());
return dice(generator);
}
在https://ideone.com/d7Ajfk上查看它。
如果您能够使用 C++17,则可以使用与您尝试使用的代码类似的代码if constexpr
template<typename TYPE>
TYPE generateRandom()
{
std::random_device randomDevice;
std::mt19937_64 generator(randomDevice());
if constexpr ( std::numeric_limits<TYPE>::is_integer )
{
std::uniform_int_distribution<TYPE> dice(std::numeric_limits<TYPE>::min(), std::numeric_limits<TYPE>::max());
return dice(generator);
}
else
{
std::uniform_real_distribution<TYPE> dice(std::numeric_limits<TYPE>::min(), std::numeric_limits<TYPE>::max());
return dice(generator);
}
}
虽然,我仍然鼓励使用单独的功能getDice()
template <typename TYPE>
auto getDice(std::true_type)
{
if constexpr ( std::numeric_limits<TYPE>::is_integer )
{
return std::uniform_int_distribution<TYPE>(std::numeric_limits<TYPE>::min(), std::numeric_limits<TYPE>::max());
}
else
{
return std::uniform_real_distribution<TYPE>(std::numeric_limits<TYPE>::min(), std::numeric_limits<TYPE>::max());
}
}
template<typename TYPE>
TYPE generateRandom()
{
std::random_device randomDevice;
std::mt19937_64 generator(randomDevice());
auto dice = getDice<TYPE>();
return dice(generator);
}
推荐阅读
- javascript - glb 没有出现在 three.js 中
- ado.net - 我可以在表值 SqlParameter 中放入的行数是否有限制?
- c# - 来自基类的 C# 泛型方法
- visual-studio - 构建 VS 扩展需要哪些 Visual Studio 工作负载?
- java - JVM 提交的堆内存大于 Xmx
- mysql - 等效于 Postgres 的 only_full_group_by
- android - 如何更改自定义对话框的 TextView 上的消息?
- python - 如何在 matplotlib 中使离散颜色图连续?
- react-native - 为什么我的图像在包裹在 Animated.View 中时不显示?
- reactjs - 使用 OverlayTrigger 时如何设置 Overlay 容器属性?