模板函数,生成从最小到每种类型的随机值

Template function which generate random value from min to max of every type

本文关键字:种类 类型 随机 函数      更新时间:2023-10-16

我需要编写函数的模板,该模板的类型例如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包含整数最大值和负值

我也尝试了这样的事情:

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);
}