Когда я смотрю на документацию для станд :: exponential_distribution, похоже, он не предоставляет стандартного способа изменения лямбда-параметра во время выполнения.
Eсть param
метод, но он принимает непрозрачный тип члена param_type
и единственный документированный способ получения объекта этого типа — это вызвать param
без аргументов, но это означало бы, что сначала должен быть создан другой экземпляр с этим параметром.
Ниже я показываю два недокументированных способа сброса лямбды, которые компилируются, но я не знаю, приведут ли они к правильному поведению во время выполнения.
#include <random>
#include <new>
int main(){
std::random_device rd;
std::mt19937 gen(rd());
std::exponential_distribution<double> intervalGenerator(5);
// How do we change lambda after creation?
// Construct a param_type using an undocumented constructor?
intervalGenerator.param(std::exponential_distribution<double>::param_type(7));
// Destroy and recreate the distribution?
intervalGenerator.~exponential_distribution();
new (&intervalGenerator) std::exponential_distribution<double>(9);
}
Есть ли документированный способ сделать это, и если нет, безопасны ли одно из двух решений?
Просто назначьте новый генератор старому экземпляру:
std::exponential_distribution<double> intervalGenerator(5);
intervalGenerator = std::exponential_distribution<double>(7);
Портативный, легко читаемый и, очевидно, правильный.
Также,
intervalGenerator.param(std::exponential_distribution<double>::param_type(7));
Это безопасно, как описано в 26.5.1.6/9 как в N3337, так и в N4141, так что вы можете использовать это тоже. Но с первым вариантом не возникает вопросов переносимости.
Других решений пока нет …