【发布时间】:2020-07-09 09:06:55
【问题描述】:
我有几个class A 的对象。在其他一些class B 中,我想保留class A 的unordered_set 对象集。请注意,class B 的对象因此包含一个集合,该集合可能指向(某些)与另一个集合相同的class A 对象。要求这些class A 对象永远不会被复制或任何东西,因为它们包含应该由class B 和class A 的不同对象使用和更改(共享使用)的成员数据。
首先,由于我来自 C,我想只是使用指向对象的指针作为集合中的值。但是,在编码时,我发现我现在还需要传递重写的哈希和相等功能,因为我必须比较 A 类的对象在 class A 的私有成员上是否相等。因此散列函数需要是class A 的公共成员函数。
然而我想知道,因为std::unordered_set::insert() 似乎需要对 value_type 的引用,是否可以只使用 A 作为 std::unordered_set 的值类型。这将使代码更容易一些,因为默认情况下它会使用已经在class A 中实现的== operator。但是,我不确定std::unordered_set::insert() 是否复制了您传递给它的对象。似乎没有,但 value_type 仍然是 A,而不是 A&。
我也看不出std::unordered_set::insert() 和std::unordered_set::emplace() 之间的区别。我不明白“复制与移动”是什么意思。
TLDR:为了在集合或映射中保留对用户定义类的对象的引用,在这种情况下是否可以使用A* 作为 value_type?还是std::reference_wrapper<A>?或者只是简单的A?
这是一个最小的可重现示例:
class A {
public:
bool operator== (A& other);
private:
B* b;
size_t id;
size_t someIntThatMustBeShared;
};
class B {
public:
std::unordered_set<A ? > as;
};
【问题讨论】:
-
指针和引用在 C++ 中都有其用途。您需要了解每个应该用于什么,以及何时不应该使用。对于“指针或引用”,C++ 中没有“一刀切”的答案。事实上,每个 C++ 类型的问题中的“最好做 X 还是 Y”都有相同的答案:“是”。
-
@SamVarshavchik 看来我的问题还不够清楚。我相信我充分意识到指针和引用之间的区别,我也相信我的问题表明了这一点。在这方面,当然非常感谢有关如何提高问题清晰度的任何反馈。我的意思是特别询问如何使用指针、引用或对象作为值类型,以及对于问题中描述的用例,哪一个更好。
-
您可能知道它们之间的区别,但您问这个问题是因为您不知道什么时候“最好”使用其中一个,这是我特别提到的在我的评论中。此外,如果您尝试在 unordered_set 中实际使用引用,您......将不太可能成功。在某些时候,迟早你会意识到你不能在 C++ 中做到这一点,你能做的最多就是使用
std::reference_wrapper。所以,在你开始思考哪个是“更好的选择”之前,看起来你还有更多的学习要做,在这里。 -
@SamVarshavchik 谢谢。我偶然发现了您在评论中描述的问题,并尝试使用
std::reference_wrapper实施解决方案。你提出了一个很好的观点,这在原始问题中并不清楚,我将对其进行编辑。话虽如此,我想强调我并不是在寻找任何一般的“最佳”解决方案,但我相信我已经提供了一个足够具体的用例来要求一个特定的解决方案 at all 因为我找不到在任何情况下都有效的。您是否建议我继续尝试使用 reference_wrapper? 在这种情况下是首选模式吗? -
也许吧。不能仅根据给定的信息就是否应该使用指针、引用或离散对象做出明智的决定。这取决于很多很多其他因素。 C++ 是当今使用的最复杂的通用编程语言。例如,仅基于显示的代码,答案将是“不要使用指针或引用,只需将它们存储在集合中”。当您在显示的代码中再添加一行时,答案可能会有所不同,原因可能有很多。这就是为什么 stackoverflow.com 上没有人能真正给你答案的原因。
标签: c++ pointers reference stl unordered-set