Давайте принимать uniform_int_distribution
например. На мой взгляд, несмотря на то, что он хранит набор параметров распределения по умолчанию, он практически не имеет состояния. Таким образом, не было бы лучше и удобнее проектировать его как шаблон функции, такой как
template <class Engine, class IntType = int>
IntType uniform_int(Engine& engine, IntType a = 0, IntType b = numeric_limits<IntType>::max());
Довольно часто я пишу что-то вроде
std::uniform_int_distribution<int> uniform_int(a, b);
... = uniform_int(engine);
Или сжать его в одну строку
... = std::uniform_int_distribution<int>(a, b)(engine);
В любом случае, это кажется надуманным и неловким. С функциональным интерфейсом это можно сделать естественным образом как
... = std::uniform_int(engine, a, b);
Вы все еще можете сохранить набор параметров по умолчанию, если хотите
auto my_uniform_int = std::bind(std::uniform_int<int>, placeholders::_1, a, b);
Я что-то пропустил?
На мой взгляд, несмотря на то, что он хранит набор по умолчанию
параметры распределения, это практически без состояния.
Нет, не обязательно Например, если базовый механизм генерирует X случайных битов одновременно, и uniform_int_distribution
(с заданным диапазоном) требует только Y случайных битов (где Y < X) реализация может выбрать в качестве оптимизации сохранение оставшихся случайных битов для последующего использования.
Кроме того, вы хотите сохранить единый интерфейс с такими вещами, как normal_distribution
(где многие методы генерируют 2 случайных числа одновременно, так что вы возвращаете одно и сохраняете другое для следующего вызова), и распределения, в которых вы хотите предварительно вычислить некоторые параметры во время построения.
Других решений пока нет …