【发布时间】:2019-07-20 21:55:52
【问题描述】:
我想创建一个模板随机数生成器类,它可以是整数类型或浮点类型。为什么?对于作业,我编写了一个累积函数(基本上与 std::accumulate 相同),并且我想制作一个可以是任何整数或浮点类型的测试工具(例如,unsigned|short|long|long long int、float、双倍的)。我们一直在研究模板,我正在尝试使用模板编程来做出动态的编译时决策。我可能以错误的方式处理这个问题 - 非常感谢任何建议/参考。
这是我的测试函数:
void testdrive() {
std::vector<int> vint(ELEMENTS);
std::vector<double> vflt(ELEMENTS);
RNG<int> intrng;
RNG<double> fltrng;
std::generate(vint.begin(), vint.end(), intrng)
std::generate(vflt.begin(), vflt.end(), fltrng)
std::cout << "Sum of " << printvec(vint) << "is " accum(vint) << "\n\n";
std::cout << "Sum of " << printvec(vflt) << "is " accum(vflt) << '\n';
}
我不知道如何为我的班级使用模板编程来做到这一点。我想要做的是,如果类型是 int 类型,则使用 uniform_int_distribution,如果是 float|double,则使用 uniform_real_distribution。我意识到这两者并不完全可以互换,但对于我正在尝试做的事情来说这很好。这是我的课:
template<typename T>
class RNG {
public:
RNG(T low=std::numeric_limits<T>::min(),
T high=std::numeric_limits<T>::max())
: rng_engine{rng_seed()}, rng_dist{low, high}, rng_low{low},
rng_high{high} { }
RNG(const RNG& r): rng_engine{rng_seed()}, rng_dist{r.rng_low,
r.rng_high}, rng_low{r.rng_low}, rng_high{r.rng_high} { }
T operator()() { return rng_dist(rng_engine); }
private:
std::random_device rng_seed;
std::mt19937 rng_engine;
template<typename U, typename=std::enable_if_t<std::is_integral<T>::value>>
std::uniform_int_distribution<T> rng_dist;
template<typename U, typename=std::enable_if_t<std::is_floating_point<T>::value>>
std::uniform_real_distribution<T> rng_dist;
T rng_low, rng_high;
};
另外,对于阅读这篇文章的任何人,我发现这本书对于深入了解 C++ 模板非常有帮助:C++ 模板 - 完整指南第 2 版 (http://www.tmplbook.com/)
【问题讨论】:
-
为什么要这样做?为什么要将生成器与发行版捆绑在一起,并将发行版绑定到与其没有关联的类型?特别是考虑到
uniform_int和uniform_real的行为不同(后者提供半开范围,而前者是封闭范围)。 -
@NicolBolas 感谢您的关注。我修改了我的问题,希望能回答你的问题。如果没有,请告诉我。