这是从容器中获取随机元素的OK范围的方法吗

Is this the OK scoped way to get random element from the container?

本文关键字:元素 OK 范围 方法 随机 获取      更新时间:2023-10-16

最近我决定试用新的c++11随机库,我想到了一件事。。。从容器中拾取随机元素时,要去掉[rand((%nelements]。原因是我想要可重复的生成,当使用rand封装是不存在的,因为

auto set_a=generateSet(nelements1); //generateSet calls rand
auto set_b=generateSet(nelements2); //so set_b is determined by the previous line :(

这就是我的想法:(注意,这不是线程安全的,它的设计是安全的,调用generateSet不会相互影响(通过更改rand内部值的状态(

template<typename container_type,typename element_type >
class RandElemGetter
{
    const container_type& containter_ref;
    std::uniform_int_distribution<size_t> distribution;
    std::mt19937 engine;
public:
    RandElemGetter(container_type& container): containter_ref(container),distribution(0,container.size()-1)
    {
    }
    element_type get()
    {
        return containter_ref[distribution(engine)];
    }
};

用法:

{
vector<int> v{1,2,3,1701,1729};
vector<int> result;
RandElemGetter<vector<int>,int> reg_v(v);
for(size_t i=0;i<nelements;++i)
result.push_back(reg_v.get());
}

那么这个解决方案可以吗?我知道这不是线程安全,这不是重点。我想知道是否有更好的"作用域"方法从随机访问容器中获取随机元素。可以使用std::advanced对其进行修改,以便为所有人工作。

RandElemGetter(container_type container):
   containter_ref(container),distribution(0,container.size()-1)

这将按值获取容器,创建一个临时副本,并存储对该副本的引用。构造函数完成后,引用无效。

您需要存储副本,或者通过引用传递参数。无论如何,通过常量引用传递复杂对象是个好主意,以避免不必要的复制。

  • 我会使用<typename container_type, typename value_type = container_type::typename value_type>。STL容器的value_types有typedef,所以通常不需要重复
  • 正确的解决方案确实是返回*std::advance(containter_ref.begin(), distribution(engine));
  • 我将get()重命名为operator(),并提供一个result_type typedef以符合STL模型AdaptableGenerator

您可能希望在SGI的random_sample处有一个来自原始STL的峰值;我相信GNU仍然将其作为一个扩展。