如何使用 std::shuffle 以随机序列对具有唯一指针的向量进行混洗?

Posted

技术标签:

【中文标题】如何使用 std::shuffle 以随机序列对具有唯一指针的向量进行混洗?【英文标题】:How can I shuffle a vector with unique pointers in a random sequence with std::shuffle? 【发布时间】:2017-01-21 19:26:32 【问题描述】:

我正忙于编写纸牌游戏。对于这个纸牌游戏,我想洗牌。甲板是唯一指针的向量,看起来像这样:

std::vector<std::unique_ptr<Cards>> _deck;

我尝试使用 shuffle 函数从其中获取随机序列,但出现以下错误:“没有函数模板实例“std::shuffle”与参数向量匹配”。查看下面的代码块以获取参数.

std::shuffle(_buildings_deck.begin(), _buildings_deck.back(), std::default_random_engine);

据我所知,我使用的参数是正确的,我仍然需要选择一个随机引擎,但这不应该是问题。所以我想知道是否可以使用 shuffle 来随机排序唯一指针向量,如果可以,如何?

【问题讨论】:

随机播放 reference_wrapper (en.cppreference.com/w/cpp/utility/functional/reference_wrapper) 的向量(或列表)。 Card 不是整数有什么原因吗?你为什么在这里使用堆分配的东西? @JesperJuhl 我试过这段代码:“std::vector<:reference_wrapper>> ref(_buildings_deck.begin(), _buildings_deck.end()); std::shuffle (ref.begin(), ref.end(), std::mt19937 std::random_device() );"。但现在我得到了我试图引用已删除函数的错误。我知道在没有好的复制构造函数的情况下尝试复制变量是一个常见错误。而且因为我使用的是唯一指针,所以无法复制变量。那么这可能是问题所在吗?还是我写了一段糟糕的代码? @NicolBolas Card 是一个对象。我使用工厂设计模式来构建卡片对象。因为 card 是一个抽象类,我无法在没有指针的情况下返回它。我对 C++ 有点陌生,所以我不知道在我想将指针添加到列表时立即取消引用指针是否是一个好习惯?所以我会有一个对象列表,而不是一个具有唯一指针的列表。 【参考方案1】:

std::shuffle() 期望随机访问迭代器与 std::vector 一样。你必须用 std::vector 替换 std::list。

【讨论】:

任何随机访问迭代器都可以。您可以使用 std::array、std::deque 和 std::vector。 他可以只创建一个 reference_wrapper 向量,然后对其进行随机播放以获得列表的随机视图。

以上是关于如何使用 std::shuffle 以随机序列对具有唯一指针的向量进行混洗?的主要内容,如果未能解决你的问题,请参考以下文章

C++ STL应用与实现64: 如何使用shuffle和random_shuffle : 洗牌 (since C++11)

如何以编程方式设置特定序列的音频文件?

[HAOI2006] 均分数据 - dp,随机化

P2503 [HAOI2006]均分数据

`rand()` 的用处 - 或者谁应该调用 `srand()`?

如何使用顺序 ID 从 Firebase 检索随机对象?