比较cppreference.com 和Microsoft reference 的std::discrete_distribution:
这些是VS2013提供的构造函数:
discrete_distribution();
explicit discrete_distribution(
const param_type& par0
);
discrete_distribution(
initializer_list<double> IList
);
template<class Fn>
discrete_distribution(
size_t count,
double low,
double high,
Fn func
);
缺少一个重要的构造函数,可能是因为微软开发人员没有时间实现它:
template< class InputIt >
discrete_distribution( InputIt first, InputIt last );
这意味着,除非文档不完整,否则您根本不能为此类使用基于迭代器的构造函数。切换到另一个编译器(如 clang 或 g++),或等到此功能实现。
现在可以使用的解决方法:
std::size_t i(0);
assert( !weights.empty() ); // No weights would be very weird.
std::discrete_distribution<> dist(weights.size(),
0.0, // dummy!
0.0, // dummy!
[&weights,&i](double)
{
auto w = weights[i];
++i;
return w;
});
我希望至少支持 lambdas ;-) 重要的是通过引用捕获 i,这样它就可以正确递增。演示:http://ideone.com/nIBUts
为什么会这样?我们这里使用的构造函数是:
template< class UnaryOperation >
discrete_distribution( std::size_t count, double xmin, double xmax,
UnaryOperation unary_op );
documentation on cppreference 告诉我们count(在我们的例子中为weights.size())以及xmin 和xmax 用于使用UnaryOperation 创建权重。
我们忽略 xmin 和 xmax 是故意的。作为UnaryOperation,我们使用lambda
[&weights,&i](double)
{
auto w = weights[i];
++i;
return w;
}
或
[&weights,&i](double)
{
return weights[i++];
}
如果你愿意的话。
现在,我们忽略该运算符的输入值,只返回向量的第 i^th 个元素。我们通过引用捕获向量和索引以避免复制。