在集合之间移动 `unique_ptr`

8

我有两个集合和一个指向 a 元素的迭代器:

set<unique_ptr<X>> a, b;
set<unique_ptr<X>>::iterator iter = find something in a;

我想从a中删除iter所指向的元素,并将其插入到b中。这是否可能? 如何实现?


@black:我相信这个问题是自包含的。如果你足够聪明能够回答,那么问题对你来说应该是显而易见的。 - Yakov Galka
在我看来,问题应该在问题中显而易见,不需要你编写代码来展示。我遇到的问题可能与你遇到的不同。我遇到了const的问题,你呢? - edmz
2
@black:你不需要编写任何代码。事实上,我甚至没有尝试编译任何代码,因为我非常了解这种语言,知道插入和删除操作是行不通的。这个问题是针对那些非常熟悉C++标准的人,他们可以指出std::set接口的特定部分或其组合,以实现我所需的功能。问题就在那里,如果你认为SO上的每个问题都会转化为编译器错误,那就太糟糕了。 - Yakov Galka
1个回答

2

嗯,我怀疑没有正常的方法来做到这一点。但总有一种非正常的方法 :) 你可以按照以下步骤进行:

auto tmp = const_cast<std::unique_ptr<std::string>&&>(*iter);
a.erase(iter);
b.insert(std::move(tmp));

好的,第一行违反了set不变量,这很糟糕,但据我所知,这不应该是一个问题,因为在下一行我们就将这个恶意节点从集合中删除了。


1
这样做会不会在擦除时使 unique_ptr 失效? - Tasos Vogiatzoglou
@TasosVogiatzoglou,不会的。我们将对象从集合a移动到tmp,在擦除时,集合a包含“已移动”的unique_ptr对象。 - ixSci
哦,好的。当我阅读它时,我认为在擦除时调用了删除器。 - Tasos Vogiatzoglou
2
这违反了set不变量,以至于我无法确定每个rb-tree实现在违规节点被删除后是否会产生有序的rb-tree... 看来这是不可能的... - Yakov Galka
实际上,我可以想象出一种红黑树的实现方式,它会在这段代码上失败。考虑一种不存储父节点指针的实现方式,并通过从根节点开始搜索来进行删除操作。不确定这是否符合标准,但除此之外,它是一个合法的红黑树实现。 - Yakov Galka
我认为任何合理的实现都不会在迭代器删除时使用值比较。即使它从根节点遍历整棵树,也会使用存储在迭代器中的一些内部数据进行比较。在这种情况下进行值比较是愚蠢的。但无论如何,正如我所说,我的解决方案并不完美,但我想不出其他更好的方法。除了复制存储在“unique_ptr”中的内容以创建一个新的“unique_ptr”。但这不是你要求的。 - ixSci

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接