Reputation: 2438
So I want to write a function that measures the runtime of a random number generation. To be able to use different random engines and distributions, I use templates for those, but I also need a template parameter to initialize the vector I write the numbers in.
template<typename T_rng, typename T_dist, typename T_vectype>
double timer_gen(T_rng& rng, T_dist& dist, int n){
std::vector< T_vectype > vec(n, 0);
auto t1 = std::chrono::high_resolution_clock::now();
for (int i = 0; i < n; ++i)
vec[i] = dist(rng);
auto t2 = std::chrono::high_resolution_clock::now();
auto runtime = std::chrono::duration_cast<std::chrono::microseconds>(t2-t1).count()/1000.0;
return runtime;
}
int main(){
const int n = 1000;
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::minstd_rand rng_minstd (seed);
std::uniform_real_distribution<double> dist_double(0.0, 1.0);
double runtime_double_minstd = timer_gen<std::minstd_rand, std::uniform_real_distribution<double>, double>(rng_minstd, dist_double, n);
}
This works! But I feel like there must be a better way for the last line. the first two template parameters could be deduced implicitly, I only need to list them because the third needs to be set to int. Is there a better way to do this?
Upvotes: 1
Views: 845
Reputation: 96790
One option is to rearrange the order of the template parameters so that the value_type
of the vector is specified first. Another option is to set T_vectype
as a default template parameter to typename T_dist::result_type
which is the exposed typedef aliasing the type you specified for the random number generator.
Upvotes: 1
Reputation: 171097
Yes, change the order of the parameters:
template<typename T_vectype, typename T_rng, typename T_dist>
double timer_gen(T_rng& rng, T_dist& dist, int n){
// .. as before
}
int main(){
const int n = 1000;
unsigned seed = std::chrono::system_clock::now().time_since_epoch().count();
std::minstd_rand rng_minstd (seed);
std::uniform_real_distribution<double> dist_double(0.0, 1.0);
double runtime_double_minstd = timer_gen<double>(rng_minstd, dist_double, n);
}
If you specify less explicit template arguments than there are template parameters, the compiler will (try to) deduce the rest. That also covers the case of "no arguments specified explicitly."
Upvotes: 1