c++ - 如何设计一个带有可选随机种子参数的函数以传递给 mt19937
问题描述
在 RI 中可以构建以下roll_die(seed = NULL)
函数,该函数返回 1 到 6 之间的随机整数,并且它允许为 RNG 指定种子的选项。
roll_die_r <- function(seed = NULL){
# Returns a random number between 1 and 6
# Optionally specify a RNG seed
set.seed(seed)
return(sample(x = 1:6, size = 1L))
}
这很好,因为我可以使用默认值调用它seed = NULL
并返回一个随机值,或者我可以使用指定的种子值调用它,这样我就可以获得可重现的结果。
roll_die_r() # random
roll_die_r(seed = 0) # always returns 6
如何使用mt19937在 c++ 中实现相同的功能?我能想到的最好的是
#include <Rcpp.h>
#include <random>
using namespace Rcpp;
// [[Rcpp::plugins(cpp11)]]
// [[Rcpp::export]]
int roll_die_cpp(int seed = -1){
// Returns a random integer between 1 and 6
// Optionally specify a RNG seed
std::mt19937 mt;
// Seed the RNG
if(seed == -1) seed = std::random_device{}();
mt.seed(seed);
std::uniform_int_distribution<int> dist(1, 6);
int result = dist(mt);
return result;
}
但这并不理想,因为用户可能会意外地call roll_die_cpp(seed = -1)
期望得到可重现的结果,但事实并非如此。
roll_die_cpp() # random
roll_die_cpp(seed = 0) # always returns 5
roll_die_cpp(seed = -1) # random
我的问题不是专门关于roll_die()
方法或随机数生成器 - 它更多的是关于功能设计。在 RI 中经常使用默认参数设置为 NULL 的函数,但我不知道如何在 c++ 中完成同样的事情。
更新:这是我得到的另一个例子。
函数
return_0 <- function(msg = NULL){
if(!is.null(msg)) print(msg)
return(0L)
}
return_0() # doesn't print a message
return_0("hello world") # prints hello world
cpp函数
// [[Rcpp::export]]
int return_0_cpp(std::string msg = "don't print"){
if(msg != "don't print") Rcpp::Rcout << msg;
return(0);
}
return_0_cpp() # doesn't print a message
return_0_cpp(msg = "hello world") # prints hello world
return_0_cpp(msg = "don't print") # doesn't print a message
注意有多尴尬return_0_cpp()
。我在 R 中创建的 cpp 中的一种干净的方式是什么?
解决方案
在 RI 中经常使用默认参数设置为 NULL 的函数,但我不知道如何在 c++ 中完成同样的事情。
std::optional
(C++17 起) 用于可选值:
#include <iostream>
#include <optional>
void fun(std::optional<int> v = std::nullopt) {
if (v) {
std::cout << "value passed = " << v.value();
} else {
std::cout << "no value passed";
}
}
int main(){
fun();
fun(4);
}
作为旁注:根据传递的参数数量,我会小心地让同一个函数做两件不同的事情。有人可能会说
dice.seed(0);
auto x = dice.roll();
比
auto x = dice.roll(0);
推荐阅读
- javascript - 使用 React 将动态画布作为 div 的背景
- javascript - 类型错误:尝试使用本地存储而不是使用状态时无法读取未定义的属性“地图”
- access-token - 如何为谷歌服务帐户生成令牌
- regex - 是否有 Notepad++ RegEx 可以删除除数字和空格之外的所有内容?
- java - 离散余弦变换实现
- node.js - 反应脚本构建失败
- ruby - 如何连接到 dockerized Sinatra 应用程序
- r - 使用 dplyr 进行自适应范围的逐行操作
- android - 即使从清单中删除了权限,如何摆脱敏感的权限表单?
- c# - 提高 ASP .NET Core 3.1 和 Entity Framework Core 的并发性能?