【问题标题】:Creating a shared_ptr of vector in C++ [duplicate]在 C++ 中创建向量的 shared_ptr [重复]
【发布时间】:2016-04-18 14:24:15
【问题描述】:

在现代 C++ 中,我们可以像这样初始化一个向量:

std::vector<int> v = { 1, 2, 3, 4, 5 };

但是如果我尝试创建一个指向向量的智能指针,这将无法编译:

auto v = std::make_shared<std::vector<int>>({ 1, 2, 3, 4, 5 });

有没有比创建后使用push_backs 更好的选择?

【问题讨论】:

  • 为什么要将向量放在堆上?向量中的数据已经在堆中,因此“堆栈”中向量的大小非常小。
  • 一个类中有一个私有类成员vector,我通过getter 将它暴露给其他类。因此,我没有按值传递它,而是返回一个 shared_ptr 给它。
  • 然后引用返回。
  • @NathanOliver 可能有数百万个理由共享向量的所有权,这是完全合法的问题,我不明白为什么有人 -1 它
  • 对 gcc 来说最糟糕的是它会为列表中的 2 个元素编译,但会调用另一个构造函数。非常危险,对我来说似乎是语言缺陷。

标签: c++ c++11 vector std


【解决方案1】:
auto v = std::make_shared<std::vector<int>>(std::initializer_list<int>{ 1, 2, 3, 4, 5 });

这是有效的。如果没有直接指定 initializer_list,编译器似乎无法吃掉 make_unique 参数中的 {}。

小修改 - 使用 MSVC 2015

【讨论】:

  • 效果很好!奇怪为什么编译器无法推断类型。
  • @Crossfire 那是因为花括号初始化列表没有类型。
  • 在问题结束时将此作为评论发布;你也可以auto is = {1, 2, 3, 4, 5}; auto v = std::make_shared&lt;std::vector&lt;int&gt;&gt;(is);auto 总是将 braced-init-list 推导出为 std::initializer_list
  • @NathanOliver auto myList = {1, 2, 3, 4}; 会有一个类型,它会被推导出为std::initializer_list&lt;int&gt;
  • @TobiMcNamobi 我在查找标准时遇到问题,但从en.cppreference.com/w/cpp/language/list_initialization 我们有 braced-init-list 不是表达式,因此没有类型,例如decltype({1,2}) 格式不正确。。有关更多信息,请参阅链接中的注释部分
【解决方案2】:

您也可以通过直接在参数中创建另一个向量来移动它:

auto v = std::make_shared<std::vector<int>>(std::vector<int>({ 1, 2, 3, 4, 5 }));

【讨论】:

  • 所以您使用std::initializer_list 来初始化-构造一个std::vector,该std::vector 用于复制-构造一个包含在std::shared_ptr 中的std::vector。奇怪的。有趣的。不过是合法的。
  • @TobiMcNamobi 要挑剔:移动构造,而不是复制构造。
  • @zenith C++ 功能强大、复杂且复杂。不挑剔,但最重要的是要谈细节。事实上,细节就是整个网站的意义所在,不是吗?所以,谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-28
  • 1970-01-01
  • 2013-07-16
  • 2017-05-25
  • 1970-01-01
  • 2021-09-05
相关资源
最近更新 更多