I want to create a template random number generator class which can either be an integer type or floating point type. Why? For an assignment I wrote an accumulate function (essentially the same as std::accumulate) and I want to make a test harness which can be any integer or floating point type (e.g., unsigned|short|long|long long int, float, double). We've been studying templates and I'm trying to get my arms around using template programming to make dynamic compile-time decisions. I may be approaching this the wrong way - any suggestions/references greatly appreciated.
Here's my test function:
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';
}
I can't figure out how to do this with template programming for my class. What I want to do is if the type is an int type use uniform_int_distribution and if it's float|double use uniform_real_distribution. I realize the two aren't exactly interchangeable but for what I'm trying to do it's fine. Here's my class:
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;
};
Also, for anyone reading this post I've found this book extremely helpful for diving into C++ Templates: C++ Templates - The Complete Guide 2nd Edition (http://www.tmplbook.com/)
uniform_intanduniform_realdon't have the same behavior (the latter provides a half-open range, while the former is a closed range). - Nicol Bolas