mardi 15 mars 2016

Can I assign a Random Engine to a variable without having template vars everywhere?

I want to assign a random engine to a variable.

Underlying reason: I want to be able to switch the random engine between tests and production code. Tests should use a more predictable random generator than the production code.

Using the example code below it works, but I have to drag that <T> through all of my code, which I do not want to.

#include <random>
#include <iostream>

class MyEngine {
public:
    typedef int result_type;

    result_type operator()() {
        return 42;
    }

    constexpr result_type min() {
        return 0;
    }

    constexpr result_type max() {
        return 100;
    }
};

template <class T>
struct EngineHolder {
    T engine;

    EngineHolder(const T& engine) : engine(engine) { }
};


//template <class T>
void doSomeWork(EngineHolder/*<T>*/* engineHolder) {
    std::uniform_int_distribution<int> distribution(30, 50);

    for (int i = 0; i < 50; i++) {
        int v = distribution(engineHolder->engine);
        std::cout << v << " ";
    }
    std::cout << std::endl;
}


int main() {
    // Engine 1
    std::default_random_engine engine1;
    EngineHolder<std::default_random_engine> foo1(engine1);
    doSomeWork(&foo1);

    // Engine 2
    std::default_random_engine engine2(145457);
    EngineHolder<std::default_random_engine> foo2(engine2);
    doSomeWork(&foo2);

    // Engine 3
    std::linear_congruential_engine<unsigned int, 1, 1, 10> engine3;
    EngineHolder<std::linear_congruential_engine<unsigned int, 1, 1, 10>> foo3(engine3);
    doSomeWork(&foo3);

    // My Engine
    MyEngine myEngine;
    EngineHolder<MyEngine> foo4(myEngine);
    doSomeWork(&foo4);

    return 0;
}

I thought of making the preprocessor do the trick by defining a macro which engine to use.
Now I am wondering is there yet another way?




Aucun commentaire:

Enregistrer un commentaire