您的位置:首页 > 理论基础 > 数据结构算法

自定义数据结构想要使用 std::set 需要重载哪些操作符

2017-09-20 23:59 417 查看

一、引言

最近在自己的项目中,定义了一个自定义数据结构,在使用这个数据结构的过程中,创建了许多该结构对象,想要使用 std::set 去重处理,然而此时就发生了编译错误:

error C2678: 二进制“<”: 没有找到接受“const Point”类型的左操作数的运算符(或没有可接受的转换)



二、探索

那么这是什么原因呢?

跟进编译错误的我发现,这应该就是
<
操作符未重载的问题,也就是说:

在使用 std::set 的过程中, std::set 会默认调用自定义数据结构的
operator<
操作符函数来比较两个对象的大小来进行排序(std::set 是有序的关联容器)

于是我就添加了如下的自定义结构定义:

// User defined data structure
struct Point
{
// Default constructor
Point() : x(0), y(0) {}
// Constructor
Point(int x, int y) : x(x), y(y) {}
// Operator < override
bool operator<(const Point& rhs)  {
return (x + y) < (rhs.x + rhs.y);
}
// Member
int x;
int y;
};


让我们再进行编译:

error C2678: 二进制“<”: 没有找到接受“const Point”类型的左操作数的运算符(或没有可接受的转换)

诶!怎么还是同样的错误,并且提示没有找到接受
const Point
类型的左操作数的运算符,难道我们定义的重载操作符不能使用吗?

我开始查询资料:

在C++中,只有被声明为const的成员函数才能被一个const类对象调用。

当我看到了这一句的时候,我才醒悟过来,我们的操作符函数需要被定义成安全的 const 成员函数,其中 std::set 默认调用了不修改自定结构的值的
operator<
操作符,因此我们应该提供 const 版本的操作符重载版本:

// Operator < override
bool operator<(const Point& rhs) const {
return (x + y) < (rhs.x + rhs.y);
}


当修改之后我们再编译,发现终于可以通过了。

三、总结

在利用自定义数据结构套用 STL 的时候,需要对 STL 的模板特性有一定的了解。

比如说,std::set 是有序的,它就需要你重载一个
operator<
操作符;再比如说,你想要利用 std::find 来将一个 std::vector 中的自定义数据结构对象进行查找,这里就隐含需要调用自定义数据结构的
operator==
操作符。

一切看似奇怪的行为,其背后都有着这样或那样的必然原因。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息