C++中如何将随机分布函数作为参数传入自定义函数
实现方案
方案1:模板参数实现(编译期确定分布,性能最优)
这种方式没有额外运行时开销,适合大部分编译期就能确定分布类型的场景,直接把分布类型作为模板参数传入即可,修改后的代码如下:
#include <vector> #include <random> #include <algorithm> #include <functional> // 模板参数Dist为随机分布类型 template<typename Dist> auto GenerateRandomVector(Dist& dist, int VecSize) -> std::vector<double> { std::random_device rnd_device; std::mt19937 mersenne_engine {rnd_device()}; auto gen = [&dist, &mersenne_engine]() { return dist(mersenne_engine); }; // 修正原代码的类型不匹配问题:原代码定义了vector<int>但返回值是vector<double> std::vector<double> vec(VecSize); std::generate(vec.begin(), vec.end(), gen); return vec; }
调用示例:
// 正态分布调用 std::normal_distribution<double> normal_dist(0.0, 1.0); auto normal_vec = GenerateRandomVector(normal_dist, 100); // 均匀分布调用,直接换分布对象即可 std::uniform_real_distribution<double> uniform_dist(0.0, 10.0); auto uniform_vec = GenerateRandomVector(uniform_dist, 100);
方案2:std::function封装(运行时动态切换分布)
如果需要在运行时动态更换分布类型,不用修改函数模板,可以把分布的调用封装成std::function<double()>传入:
auto GenerateRandomVector(std::function<double()> gen, int VecSize) -> std::vector<double> { std::vector<double> vec(VecSize); std::generate(vec.begin(), vec.end(), gen); return vec; }
调用示例:
std::random_device rnd_device; std::mt19937 mersenne_engine {rnd_device()}; // 正态分布场景 std::normal_distribution<double> normal_dist(0.0, 1.0); auto normal_gen = [&normal_dist, &mersenne_engine](){ return normal_dist(mersenne_engine); }; auto normal_vec = GenerateRandomVector(normal_gen, 100); // 泊松分布场景 std::poisson_distribution<int> poisson_dist(5); auto poisson_gen = [&poisson_dist, &mersenne_engine](){ return poisson_dist(mersenne_engine); }; auto poisson_vec = GenerateRandomVector(poisson_gen, 100);
注意点
- 原代码中
mean、SD、VecSize参数不需要传非const左值引用,改为值传递或const引用即可,避免外部变量被意外修改 - 原代码存在vector类型不匹配问题,返回值声明为
std::vector<double>但内部定义的是std::vector<int>,需要修正类型一致
内容的提问来源于stack exchange,提问作者Steveit
相关产品推荐
相关产品推荐

