【问题标题】:cannot reset std::shared_ptr object inside std::set<>... why?无法在 std::set<> 中重置 std::shared_ptr 对象...为什么?
【发布时间】:2020-09-25 11:20:48
【问题描述】:

在下面的c++中调用reset()里面的list、vector、map既没有错误也没有警告。

但是,当我尝试在 set 中执行此操作时出现错误。

错误消息是[没有匹配的成员函数调用'reset']

为什么会这样???有人可以与社区分享您的知识吗?

std::shared_ptr<int> sp;
sp.reset(new int(11));
sp.reset();

std::map<int, std::shared_ptr<int>> my_map;
for (auto it = my_map.begin(); it != my_map.end(); ++it) {
  it->second.reset();
  (*it).second.reset();
}

std::list<std::shared_ptr<int>> my_list;
for (auto& x : my_list) {
  x.reset();
}

std::vector<std::shared_ptr<int>> my_vec;
for (auto it = my_vec.begin(); it != my_vec.end(); ++it) {
it->reset();
  (*it).reset();
}

std::set<std::shared_ptr<int>> my_set;
for (auto& x : my_set) {
  x.reset();      // ERROR!!!
}

for (auto it = my_set.begin(); it != my_set.end(); ++it) {
  it->reset();    // ERROR!!!
  (*it).reset();  // ERROR!!!
}
  • 操作系统:Ubuntu18.04
  • 编译器:g++ 7.5.0-3ubuntu1~18.04

【问题讨论】:

  • 请不要在您显示的minimal reproducible example 中添加行号,这让我们很难复制它来尝试自己。如果您想指出一些特定的行,请在这些行上添加 cmets 并在主要问题正文中提及它们。
  • std::set&lt;&gt; 的键是const,这是有充分理由的。如果它们被更改,这可能会违反它们的顺序,但明确定义的顺序对于std::set(用于查找)至关重要。因此,我确信for (auto&amp; x : my_set) 中的auto&amp; 会导致const 引用,而std::shared_ptr 中显然没有reset() const
  • 修改键可能会破坏作为集合的属性;每个值只出现一次。 (它也可能会破坏排序,但我认为这是一个较小的问题。)
  • @Someprogrammerdude 我编辑删除了行数,谢谢

标签: c++ c++11 smart-pointers stdset


【解决方案1】:

主要问题是std::set 是一个有序 容器,并且仅在插入时进行排序。

为了保持顺序,集合中的所有键都是常量并且不能被修改。

尝试修改std::map 的密钥时也会遇到同样的问题。

【讨论】:

  • 实践中这个问题的一般解决方案(取出值,然后有选择地放回去)可能会改善这个答案。当然,OP 必须关心迭代器的失效。
  • 我有点理解这个答案,而不是。我想我一直在使用 std::set 却没有真正理解它。
  • 但我仍然不明白修改对象“内部”的数据会影响容器的排序方式。虽然我更改了由 shared_ptr 管理的指向对象,但它仍然是相同的 shared_ptr,不是吗?
  • @KiseongYoo 假设您有一组整数(例如std::set&lt;int&gt;),其中有两个键12。当您遍历该集合时,它们将按12 的顺序出现。现在假设您想将密钥1 修改为3?由于仅在将键添加到集合时才进行排序,而不是动态地进行排序,这意味着3 会突然变得比2“小”(迭代时出现在2 之前)。然后将不再订购该套装。因此,您不能修改集合中的键。
  • 现在我明白了。在 std::set 中,值本身与自己的键密切相关,因此我们无法修改该值。非常感谢?
猜你喜欢
  • 1970-01-01
  • 2020-11-04
  • 1970-01-01
  • 2017-06-11
  • 2015-07-23
  • 1970-01-01
  • 2011-08-20
  • 2017-08-15
相关资源
最近更新 更多