【问题标题】:Use std::random_shuffle with std::array将 std::random_shuffle 与 std::array 一起使用
【发布时间】:2012-05-03 20:38:54
【问题描述】:

我有这样的代码:

typedef intptr_t ptr_t;

const int num_elements = 100;
ptr_t *pstr = (ptr_t *)malloc(sizeof(ptr_t) * num_elements);
std::array<ptr_t,num_elements> *parray = new (pstr) std::array<ptr_t,num_elements>;

我希望能够将元素 1 打乱到 num_elements-2 ,所以我想使用 std::shuffle。

auto s = parray->begin()++;
auto e = parray->end()--;
std::random_shuffle ( s, e );

我收到一个抱怨,说这个函数没有重载。 我无法看到自己做错了什么,我感到非常愚蠢。我该怎么做?

编辑:由于答案和反馈,它已更改为

auto s = parray->begin();
s++;
auto e = parray->end();
std::random_shuffle ( s, e );

但是,在“auto e”上,我得到:“auto”的间接级别与“int *”不同

【问题讨论】:

  • 我以前从未见过将迭代器算法应用于end()。另外,你想++s,而不是begin()的临时。
  • 不应该ptr_t pstrptr_t* pstr
  • @zvrba:永远不要使用new[]。大错特错,难以置信。
  • 另一个快速说明:如果您正在动态分配空间,为什么不使用std::vector 来做到这一点? std::array 背后的想法是不必必须在堆上分配空间。
  • 我是第一个建议在原始数组上使用 std::array 的人,但是尝试像这样将原始数组“转换”为 std::array 似乎不是最好的主意。例如。我认为 sizeof(ptr_t) * num_elements 在技术上可能不是正确的大小。就做std::random_shuffle(pstr+1, pstr+num_elements-1);

标签: c++ stl c++11 std


【解决方案1】:

回答您的直接问题:我相信您的错误是使用后递增运算符,它在递增之前返回其原始值。由于std::array迭代器基本上都是指针,试试

auto s = parray->begin() + 1;
auto e = parray->end() - 1;

编辑: 现在,至于其余的。你到底为什么要那样做?你有没有考虑过 std::vector&lt;int&gt; arr(100) 创建一个包含 100 个元素的动态数组?它具有类似的功能,而无需直接操作指针?

编辑 2:阅读您的 cmets 后,我意识到问题在于您正在尝试对作为指针给出的数组进行洗牌。在那种情况下,我根本不会做新的安置。假设你有 pstr 中的指针,这应该可以工作。

std::random_shuffle(pstr +1, pstr + num_elements - 1);

这是可行的,因为数组中的简单指针将作为随机访问迭代器用于算法库。

【讨论】:

  • 已编辑问题。而且,至于我为什么使用直接指针,这是一个很长的故事,但对我的使用来说是有意义的。
  • 嗯,这行得通。谢谢!仍然很想知道为什么它不适用于数组迭代器,但你解决了我的问题
  • @std''OrgnlDave : 没有数组迭代器 -- std::array&lt;T&gt;::begin()std::array&lt;T&gt;::end() 都返回 T*
  • @ildjarn 在所有现有实现中?是的。但规范留下了std::array&lt;T,N&gt;::iteratorstd::array&lt;T,N&gt;::const_iterator 实现定义。
  • @R.MartinhoFernandes :我的意思是在 OP 的代码/编译器中,正如他的编译器错误所证明的那样。
【解决方案2】:

即使编译器允许,你的代码也不会做你想做的事。您正在尝试对从begin()/end() 返回的值使用后递增/递减,因此您仍将原始值分配给se,然后(如果可能)递增/减少他们返回的临时人员。您显然想更改分配的值。

auto s= parray->begin();
auto e= parray->end();

++s;
--e;

std::random_shuffle(s, e);

或者,因为你显然有随机访问迭代器:

 std::random_shuffle(parray->begin()+1, parray->end()-1);

我不确定您为什么要动态分配 std::array——这似乎完全违背了使用 std::array 开始的意义。

【讨论】:

  • 按您说的编辑问题,不起作用。见编辑。但是,将 std::array 放置在数组顶部是简化此问题的一部分,它不是代码的实际顺序
  • @std''OrgnlDave:您在编辑中引用的问题听起来很像编译器问题——auto 的全部意义在于它应该生成正确的类型以匹配被赋值的值。如果是这样,将其更改为 int *s=...; int *e=...; 可能是最简单的
猜你喜欢
  • 2020-07-23
  • 2021-10-01
  • 2015-06-21
  • 2014-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-13
  • 1970-01-01
相关资源
最近更新 更多