使用运算符==时std::set中unique_ptr的深度比较
Deep Comparison of unique_ptr in std::set while using operator==
我正在尝试使用std::set
将一组unique_ptr
保存到我定义的自定义对象中。我在定义集合时提供了一个自定义比较功能(以实现深度比较)。在将元素插入集合时,此比较功能似乎可以正常工作,即具有等效内容的项目不会插入两次。
然而,如果我使用operator==
比较两个集合,它似乎被忽略了,即具有等效元素的集合被返回为不相等,而我期望(希望)它相等(因为我提供的自定义比较函数可以进行深度比较)。
比较函数是否仅在插入过程中使用?如果是这样的话,除了让operator==
进行深入比较之外,还有其他选择吗?
感谢任何指点。谢谢:)
样本代码
//
// main.cpp
// Test
#include <iostream>
#include <set>
class Person {
private:
std::string mName;
public:
Person(const std::string& name);
virtual ~Person() {}
void setName(std::string& name);
std::string getName();
};
typedef std::unique_ptr<Person> PersonUniquePtr;
Person::Person(const std::string& name)
: mName{ name }
{
}
void Person::setName(std::string& name)
{
mName = name;
}
std::string Person::getName()
{
return mName;
}
bool isLess(Person* p1, Person* p2)
{
if (p1->getName().compare(p2->getName()) == -1)
return true;
return false;
}
struct PersonUniquePtr_less {
bool operator()(PersonUniquePtr const& p1, PersonUniquePtr const& p2) const
{
return isLess(p1.get(), p2.get());
}
};
int main(int argc, const char* argv[])
{
std::set<PersonUniquePtr, PersonUniquePtr_less> personSet1;
std::set<PersonUniquePtr, PersonUniquePtr_less> personSet2;
PersonUniquePtr person1 = std::make_unique<Person>("Adam");
PersonUniquePtr person2 = std::make_unique<Person>("Adam");
personSet1.insert(std::move(person1));
personSet1.insert(std::move(person2));
std::cout << "personSet1.size(): " << personSet1.size() << std::endl; //Expected 1
PersonUniquePtr person3 = std::make_unique<Person>("Bruce");
personSet1.insert(std::move(person3));
std::cout << "personSet1.size(): " << personSet1.size() << std::endl; //Expected 2
PersonUniquePtr person4 = std::make_unique<Person>("Adam");
PersonUniquePtr person5 = std::make_unique<Person>("Bruce");
personSet2.insert(std::move(person4));
personSet2.insert(std::move(person5));
std::cout << "personSet2.size(): " << personSet2.size() << std::endl; //Expected 2
std::cout << "PersonSet1:" << std::endl;
for (auto& person : personSet1) {
std::cout << person->getName() << std::endl;
} //Prints out Adam Bruce
std::cout << "PersonSet2:" << std::endl;
for (auto& person : personSet2) {
std::cout << person->getName() << std::endl;
} //Prints out Adam Bruce
bool setsAreEqual = (personSet1 == personSet2);
if (setsAreEqual) {
std::cout << "Sets are equal" << std::endl;
} else {
std::cout << "Sets are not equal" << std::endl;
}
return 0;
}
C++11容器要求说a == b
等价于
distance(a.begin(), a.end()) == distance(b.begin(), b.end())
&& equal(a.begin(), a.end(), b.begin())
std::equal
不使用您的自定义比较,它使用operator==
您可以通过使用自定义谓词调用std::equal
来自己执行比较:
a.size() == b.size()
&& std::equal(a.begin(), a.end(), b.begin(),
[](PersonUniquePtr const& p1, PersonUniquePtr const& p2) {
PersonUniquePtr_less cmp;
return !cmp(p1, p2) && !cmp(p2, p1);
});
在C++14中,它更简单,因为std::equal
有一个新的重载,需要四个迭代器,尽管正如TemplateRex在下面的评论中指出的那样,这比手动测试a.size() == b.size()
效率低:
std::equal(a.begin(), a.end(), b.begin(), b.end(),
[](PersonUniquePtr const& p1, PersonUniquePtr const& p2) {
PersonUniquePtr_less cmp;
return !cmp(p1, p2) && !cmp(p2, p1);
});
在C++14中,您可以使用多态lambda:来保存一些类型
std::equal(a.begin(), a.end(), b.begin(), b.end(),
[](auto const& p1, auto const& p2) {
PersonUniquePtr_less cmp;
return !cmp(p1, p2) && !cmp(p2, p1);
});
相关文章:
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 为什么比较运算符如此快速
- 我可以使用 g++ 进行三种比较 (<=>) 吗?
- 比较字符数组
- 将模板化的类型与C++中的某些类/类型进行比较
- C++自定义比较函数
- 如何比较自定义类的std::变体
- 多个If语句与使用逻辑运算符计算条件的单个语句的比较
- std::设置自定义比较器
- 布尔比较运算符是如何在C++中工作的
- C++将目录中的所有文件与::filesystem进行比较
- shell排序中的交换和比较
- CLANG 编译器 说:变量"PTR"可能未初始化
- 如何在C++中比较两个char数组
- catch框架有没有办法比较流或文件
- 从文件中读取多个字节,并将它们存储在C++中进行比较
- 智能指针作为无序映射键,并通过引用进行比较
- 比较if语句中的数组值和int值
- 对于循环变体比较
- 在 gtest 中比较 ptr 和 nullptr