【问题标题】:I can't use 'fill' std::vector constructor with unique_ptrs我不能使用带有 unique_ptrs 的“填充”std::vector 构造函数
【发布时间】:2019-01-12 07:49:39
【问题描述】:

我正在尝试使用 std::vector 构造函数的“填充”版本。它将元素的数量作为第一个参数,将 const value_type& 作为第二个参数:

#include <vector>

int main()
{
    std::vector<int> v(100, 7);
    // Works, creates vector with 100 elements of int 7.

}

但是我似乎无法使用 unique_ptrs 进行这项工作:

#include <vector>
#include <memory>

int main()
{
    std::vector<std::unique_ptr<int>> v1(100, std::unique_ptr<int>());
    std::vector<std::unique_ptr<int>> v2(100, std::make_unique<int>());

}

两者都不适用于 unique_ptrs。我从 Visual Studio 2017 得到的错误是:

错误 C2280 'std::unique_ptr>::unique_ptr(const std::unique_ptr<_ty>> &)':试图 引用已删除的函数

考虑到第二个参数对向量中包含的类型进行 const 引用,我希望 std::unique_ptr() 或 std::make_unique() 可以简单地用作第二个参数。我知道它们都是临时的,但鉴于参数是 const 引用,它应该接受它,为什么它接受它的方式在我的第一个有效示例中接受整数 7 作为参数。

此外,std::unique_ptr() 看起来非常接近“最令人烦恼的解析”,但是 cppreference.com 上的示例使用它:

// Use the default constructor.
    std::unique_ptr<Vec3> v1 = std::make_unique<Vec3>();

正如我所说,这看起来有点像“最令人头疼的解析”,它是不带参数并返回 std::unique_ptr

的函数的函数签名

【问题讨论】:

  • 这个构造函数必须制作 n 个 copy 只移动类型...
  • 丢失第二个参数。只需使用var(count)。实例将是默认构造的。您的替代方法是使用 std::generate_n 之类的东西和一个 lambda 或回调来生成一个独特的、可移动的对象,并添加每个项目(如果您想要的只是一堆指向任何内容的唯一指针对象,那最终将毫无意义;第一个选项更好)。
  • 您尝试创建一个唯一指针对象的100 向量副本。还有问题:std::unique_ptr无法复制
  • @某个程序员老兄,我知道他们不能被复制,但我认为他们会搬家。
  • @Zebrafish 考虑一下。您正在尝试 fill 向量,这意味着每个元素都将具有相同的值。您如何期望单个输入值在不复制的情况下用相同的值填充 100 个元素?移动一个对象不会产生更多的副本。

标签: c++ vector unique-ptr


【解决方案1】:

您尝试使用的std::vector 构造函数必须复制提供的输入值,以便将向量填充到请求的大小。无法复制std::unique_ptr 是其最重要的功能之一,因此您不应该对您的代码不起作用感到惊讶。

如果你去掉第二个参数,向量中的每个值都将使用std::unique_ptr的默认构造函数构造;因此没有复制。无论如何,这就是你想要做的。

另请参阅:How to initialize a vector of unique_ptr with null pointers?

【讨论】:

  • 我认为向量可以包含无法复制但可以移动的元素。 Foo 仍然有一个移动构造函数/赋值运算符,这就是我认为它会起作用的原因。
  • 在试图复制对象时,发现没有复制赋值运算符或复制构造函数,是不是就使用了移动赋值运算符或移动构造函数?
  • 但是移动对创建 n(您提供的数字)值没有帮助。如果您有一个包含 n 个值的向量,则需要准确地构造 n 个值。您尝试使用的构造函数尝试通过复制您提供的值来实现此目的。移动无济于事,因为您可以随心所欲地移动一个值——它仍然只是一个。
猜你喜欢
  • 2017-10-26
  • 2014-12-26
  • 2016-04-20
  • 1970-01-01
  • 2016-03-26
  • 2023-04-08
  • 2013-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多