Home > database >  Passing uniform_int_distribution as parameter (with state)
Passing uniform_int_distribution as parameter (with state)

Time:01-28

I'm trying to write some code that will use random generators but allow you to seed it (for reproducability).

The code looks something like the following (trying to create a snippet that can be run)

#include <cstdio>                                      
#include <functional>
#include <random>

class CarterWegmanHash {
 private:
  unsigned int a_;
  unsigned int b_;

 public:
  // What should the signature of this be?
  CarterWegmanHash(int k, std::function<unsigned int()> unif_rand) {
    // Other stuff
    a_ = unif_rand();
    b_ = unif_rand();
  }
  unsigned int get_a() { return a_; }
  unsigned int get_b() { return b_; }
};

int main() {
  // Construct our uniform generator
  int n = 8;
  std::random_device rd;                                                        
  auto unif_rand = std::bind(                                                   
      // uniform rand from [0, n - 1]                                           
      std::uniform_int_distribution<unsigned int>(0, pow(2, n)),                
      std::mt19937(rd()));                                                      

  for (int i = 0; i < 5;   i) {
    // How do I call this?
    CarterWegmanHash h_k(n, unif_rand);
    printf("seeds for h_%d are %u, %u\n", i, h_k.get_a(), h_k.get_b());
  }
}

I'd like each of the CarterWegmanHash objects to be able to have different seeds from unif_rand, but (not suprisingly), they're all the same.

Passing by pointer gives me error: no matching function for call to ‘CarterWegmanHash::CarterWegmanHash, and passing by ref gives me cannot bind non-const lvalue reference of type ‘std::function<unsigned int()>&’ to an rvalue of type ‘std::function<unsigned int()>’

Is there a way to pass a random number generator like uniform_int_distribution so the state is maintained?

CodePudding user response:

You can just create your distribution and mt19937 in main and capture them in a lambda:

std::uniform_int_distribution<unsigned int> distribution(0, pow(2, n));
std::mt19937 mt(rd());
auto unif_rand = [&](){ return distribution(mt); };

Or with bind:

auto unif_rand = std::bind(std::ref(distribution), std::ref(mt));
  •  Tags:  
  • Related