【问题标题】:Making a constant unique_ptr to a const vector将常量 unique_ptr 设为常量向量
【发布时间】:2018-09-23 13:35:08
【问题描述】:

我想创建一个整数向量。一旦创建,我想洗牌 整数,以便具有随机顺序的整数。这将用于测试排序功能。

现在,不允许任何排序算法对向量进行就地排序,因此我们需要使向量成为常数。另外 - 我不希望任何人能够更改 unique_ptr 并将其指向其他内容。

第一季度。我们如何实现它。

当前解决方案:

在阅读了thisthis等参考资料后,我做了以下工作。

我正在创建一个向量,将其分配给唯一指针,以确保它可以防止内存泄漏并在超出范围时自动删除。我们将向量打乱,然后将此向量移动到类型为 (const std::vector<int>) 的新向量。然后我们将指针移动到一个 const 唯一指针。

在下面的代码中,我编写了当前解决方案。让我知道是否有更好的方法。

我正在使用 c++17 来编译程序。

#include <random>
#include <memory>
#include <algorithm>
#include <iostream>
#include <vector>

std::unique_ptr<const std::vector <int>>
createConstVector(int numberOfElements, int increments) {
    auto v = std::make_unique <std::vector<int>> (numberOfElements);
    std::random_device rd;
    std::mt19937 g(rd());
    std::generate(v->begin(), v->end(),
                  [n=0, increments] () mutable { n = n + increments; return n;});
    std::shuffle(v->begin(), v->end(), g);
    std::unique_ptr<const std::vector<int>> v2 = std::move(v);
    return std::move(v2);
}

auto sortUsingStdSort(std::unique_ptr<const std::vector<int>> const &vectorToSort) {
  auto v = std::make_unique<std::vector<int>> (*vectorToSort);

  std::sort(v->begin(), v->end());
  return std::move(v);
}

int main () {
  const std::unique_ptr<const std::vector <int>> u3 = createConstVector(10, 5);
  auto sortedVector = sortUsingStdSort(u3);
  for(auto v : *sortedVector) {
    std::cout << " " << v;
  }
}

【问题讨论】:

  • 为什么不简单地使用const vector&lt;int&gt; 而不是std::unique_ptr&lt;const std::vector &lt;int&gt;&gt;
  • 我觉得你想多了。我认为不需要unique_ptr
  • 我们说:auto sortUsingStdSort(const std::vector&lt;int&gt;&amp; vectorToSort) { std::vector&lt;int&gt; v = vectorToSort; std::sort(v.begin(), v.end()); return v; }`
  • @SaileshD 我很确定第二个链接中的规则的重点是,无论您在哪里接受const unique_ptr&lt;T&gt;&amp;,您最好只接受T*(或T&amp; ),因为无论哪种方式都没有所有权转移,而且后者更灵活。
  • @RishiAgrawal 是的,只需将向量设为自动变量即可。向量已经基本上只是其托管数组的一个 unique_ptr (有一些额外的方法来做向量的东西)。在这种情况下,没有理由动态分配向量本身。

标签: c++ c++11 c++14 c++17 unique-ptr


【解决方案1】:

以下是在没有原始指针、没有不必要的unique_ptr 使用和没有std::move 的情况下编写它的方法:

#include <iostream>
#include <random>
#include <algorithm>
#include <vector>

std::vector<int>
createVector(int numberOfElements, int increments) {
    auto v = std::vector<int>(numberOfElements);
    std::random_device rd;
    std::mt19937 g(rd());
    std::generate(v.begin(), v.end(),
                  [n=0, increments] () mutable { n = n + increments; return n;});
    std::shuffle(v.begin(), v.end(), g);
    return v;
}

auto sortUsingStdSort(std::vector<int> v) {
  std::sort(v.begin(), v.end());
  return v;
}

int main() {
  const std::vector<int> u3 = createVector(10, 5);
  auto sortedVector = sortUsingStdSort(u3);
  for(auto v : sortedVector) {
    std::cout << " " << v;
  }
}

向量通过const 引用传递,因此没有不必要的复制。向量是按值返回的,但我们也可以依靠RVO 来避免在这里复制。

创建副本的唯一位置是 sortUsingStdSort 函数的参数,我们在其中明确请求它。

【讨论】:

  • 非常感谢。这使我能够以不同的方式理解整个“const”和 unique_ptr。
  • const 在我看来是 C++ 的最佳特性之一。好好理解它,你就会情不自禁地爱上它。
  • sortUsingStdSort 也可以按值接受,而不是在正文中复制。然后避免从 r 值参数复制
  • createVector 中,我会创建rdg static
  • @RobertAndrzejuk 我不想做出超出回答问题所需的更改。这不是 codereview.stackexchange.com。
猜你喜欢
  • 2016-03-18
  • 2021-11-01
  • 2014-03-30
  • 2014-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多