Они все наследовались базовому классу? Я должен использовать шаблоны?
(Я обращаюсь к этому http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c15319/),
Я делаю это прямо сейчас:
typedef std::mt19937 RNG;
и затем
class Chooser {
public:
Chooser(RNG& rng, uint n, uint min_choices, uint max_choices):
Другими словами, я передаю ссылки на RNG. Как я передал бы в произвольном генераторе?
Кроме того, я понимаю, что это - возможно, другой вопрос, но как я передаю генератор STL?
std::random_shuffle(choices_.begin(), choices_.end(), rng);
кажется, не работает.
решение передающего генератора:
typedef std::ranlux64_base_01 RNG;
typedef std::mt19937 RNGInt;
решение передачи STL:
struct STL_RNG {
STL_RNG(RNGInt& rng): gen(rng) {}
RNGInt& gen;
int operator()(int n) { return std::uniform_int(0, n)(gen); }
};
Не все они наследуются от базы (что немного удивительно), но это не имеет значения, потому что так работают функторы C ++.
Для произвольных ГСЧ одного заданного типа вы получили это правильно, как (сейчас) опубликовано.
Если вы имеете в виду, как мне определить функцию, которая принимает любой генератор случайных чисел в качестве аргумента.
template< class RNG > // RNG may be a functor object of any type
int random_even_number( RNG &gen ) {
return (int) gen() * 2;
}
Вам не нужно использовать больше шаблонов, чем этот, из-за определения типа.
Определение одной функции для приема различных RNG сложнее, потому что семантически это требует наличия общего базового типа. Вам необходимо определить базовый тип.
struct RNGbase {
virtual int operator() = 0;
virtual ~RGNBase() {};
};
template< class RNG >
struct SmartRNG : RNGBase {
RNG gen;
virtual int operator() {
return gen();
}
};
int random_even_number( RNGBase &gen ) { // no template
return (int) gen() * 2; // virtual dispatch
}
Обернуть это в класс или функтор, который подходит для ваших нужд?
Я предлагаю два метода: объекты функций и указатели функций. В любом случае разрешите вашему классу получать объект-функцию или указатель функции на генератор случайных чисел.
С помощью объекта функции вы можете определить базовый класс и заставить свой принимающий класс реализовывать функции, требующие указателя на базовый класс объекта функции. Это дает вам больше свободы в определении множества различных функциональных объектов без изменения интерфейса принимающего класса.