0

为了了解 C++11 的复杂性,我玩unique_ptr了一下。

我想知道,有什么方法可以iota用来初始化 Containerunique_ptr吗?

我从运行良好的 unique-ptr-less 解决方案开始:

std::vector<int> nums(98); // 98 x 0
std::iota(begin(nums), end(alleZahlen), 3); // 3..100

现在让我们尽可能使用unique_ptr

std::vector<std::unique_ptr<int>> nums(98); // 98 x nullptr
std::unique_ptr three{ new int{3} };
std::iota(begin(nums), end(nums), std::move{three});

这显然失败了。原因:

  • 虽然我标记threemovea&&这可能不足以将初始值复制/移动到容器中。
  • ++initValue也不会工作,因为initValue是 type unique_ptr<int>,并且没有operator++定义。但是:我们可以定义一个自由函数unique_ptr<int> operator++(const unique_ptr<int>&);,并且至少可以解决这个问题。
  • 但是再次不允许复制/移动该操作的结果,unique_ptr这一次我看不到如何欺骗编译器使用move.

嗯,这就是我停下来的地方。我想知道我是否错过了一些关于如何告诉编译器他可能moveoperator++. 还是还有其他障碍?

4

2 回答 2

3

为了最终得到 98 个实例unique_ptr,必须有 98 次调用new. 你试图只用一个-不可能飞。

如果您真的打算将方形钉敲入圆孔,您可以执行以下操作:

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

class MakeIntPtr {
public:
  explicit MakeIntPtr(int v) : value_(v) {}
  operator std::unique_ptr<int>() {
    return std::unique_ptr<int>(new int(value_));
  }
  MakeIntPtr& operator++() { ++value_; return *this; }
private:
  int value_;
};

int main() {
  std::vector<std::unique_ptr<int>> nums(98);
  std::iota(begin(nums), end(nums), MakeIntPtr(3));

  std::cout << *nums[0] << ' ' << *nums[1] << ' ' << *nums[2];
  return 0;
}
于 2014-05-10T13:45:32.303 回答
2

也许std::generate_n是一个更好的算法?

std::vector<std::unique_ptr<int>> v;
{
    v.reserve(98);
    int n = 2;
    std::generate_n(std::back_inserter(v), 98,
                    [&n]() { return std::make_unique<int>(++n); });
}
于 2014-05-10T14:44:01.277 回答