当我从std::set或std::map为自定义类型擦除时,例如,info如果我使用https://en.cppreference.com/w/cpp/container/set/erase 中的(3) ,似乎我需要定义一个operator==for info。
但是,如果我有指向要删除的对象的迭代器,那么我相信我不需要operator==并且可以使用链接中的 (2)。但是下面的代码似乎可以编译,所以我很困惑
struct info
{
info(int i, int j, int k) : i{i}, j{j}, k{k} {}
int i;
int j;
int k;
// bool operator==(const info&rhs)
// {
// return i == rhs.i && j == rhs.j && k == rhs.k;
// }
};
struct comparer_t
{
bool operator()(const info &lhs, const info &rhs) const
{
if(lhs.i == rhs.i)
{
if(lhs.j == rhs.j)
{
return lhs.k < rhs.k;
}
return lhs.j < rhs.j;
}
return lhs.i < rhs.i;
}
};
int main()
{
std::set<info, comparer_t> s;
s.emplace(1,5,6);
s.erase(info(1,5,6));
cout << s.size() << endl;
// cout << (info(1,5,6) == info(1,5,6)) << endl;
}
Run Code Online (Sandbox Code Playgroud)
这会打印出 的大小s是0。该erase函数如何知道使用 插入的密钥emplace与我们正在搜索的不带的密钥相同operator==?
看来我需要为custom_class 定义一个运算符==。
你的解释不正确。不需要实现 operator==。
擦除函数如何知道使用 emplace 插入的密钥与我们正在搜索的没有运算符==的密钥相同?
与集合的所有比较都知道顺序的方式相同:它使用提供的比较函数(std::less默认情况下,comparer_t在您的示例中)。如果两个对象的比较都不小于另一个,则认为这些对象是等效的。
PS 在 C++20 中,我建议如下:
struct info
{
int i;
int j;
int k;
auto operator<=>(const info&) const = default;
};
int main()
{
std::set<info> s;
s.emplace(1,5,6);
s.erase({1,5,6});
}
Run Code Online (Sandbox Code Playgroud)