如何创建结构的std :: set? [英] How can I create a std::set of structures?

查看:148
本文介绍了如何创建结构的std :: set?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要创建一个 stl :: set 结构。因此,我写了以下内容:

I need to create a stl::set of structures. Therefore, I wrote the following:

stl::set <Point> mySet; // Point - name of the structure.

然后我尝试向 mySet 中添加结构实例:

Then I tried to add a structure instance to mySet as follows:

Point myPoint;
mySet.insert(myPoint);

但是,我遇到了一些编译错误(错误C2784,错误C2676):

However, I get several compilation errors (error C2784, error C2676):


1> C:\Program Files(x86)\Microsoft Visual Studio 10.0\VC\include\xfunctional(125):error C2784:bool std :: operator<(const std :: vector< _Ty,_Ax&,const std :: vector< _Ty,_Ax&)):未能将参数带到模板``const std :: vector< Ty,_Ax> &"来自 const Point

1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xfunctional(125): error C2784: bool std::operator <(const std::vector<_Ty,_Ax> &,const std::vector<_Ty,_Ax> &): failed to bring the argument to a template "const std::vector<_Ty,_Ax> &" from"const Point"

1> C:\Program Files(x86)\Microsoft Visual Studio 10.0\VC\include\xfunctional(125):错误C2676:二进制<: const Point未定义此运算符或未转换为集成运算符可接受的类型

1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\xfunctional(125): error C2676: binary "<": "const Point "does not define this operator or a conversion to a type acceptable to the integrated operator

我可以编译我的代码吗?

How do I get my code compiled?

推荐答案

std :: set 模板提供了一个关联容器,其中包含一组排序的独特的对象。其中的关键字为已排序唯一。为了支持排序,随之而来的是多种可能性,但最终所有因素都必须导致符合 严格弱

The std::set template provides an associative container that contains a sorted set of unique objects. The key words there is sorted and unique. To support sorting, a number of possibilities ensue, but ultimately the all must lead to a conforming with strict weak ordering.

std :: set 的第二个模板参数是比较类型。默认库 std :: less< Key> 由标准库提供,其中 Key 是您要存储在容器中的对象(对于您来说,是 Point )。该默认值仅使用支持键类型的任何允许的可用操作符< 生成比较。这意味着一种或另一种方式,如果您使用默认的比较器(在您的情况下为 std :: less< Point> ),则您的类必须假定这样的操作:

The second template argument to std::set is a comparison type. The default, std::less<Key>, is supplied by the standard library, where Key is the type of object you're storing in your container (in your case, Point). That default simply generates a comparison using any allowable available operator < supporting the key type. Which means one way or another, if you're using the default comparator (std::less<Point> in your case), then your class must suppose operations like this:

Point pt1(args);
Point pt2(args);

if (pt1 < pt2)  // <<=== this operation
    dosomething();

执行此操作的多种方法如下:

Multiple methods for doing this appear below:

提供成员 operator<

Provide a member operator <

到目前为止,最简单的方法是这是为您的 Point 类提供成员 operator< 的成员。这样做 pt1< pt2 生效,然后 std :: less< Point> 很高兴。假设您的课程是传统的x,y点,则如下所示:

By far the easiest method to accomplish this is to provide a member operator < for your Point class. In doing so pt1 < pt2 becomes valid and std::less<Point> is then happy. Assuming your class is a traditional x,y point, it would look like this:

struct Point
{
    int x,y;

    // compare for order.     
    bool operator <(const Point& pt) const
    {
        return (x < pt.x) || ((!(pt.x < x)) && (y < pt.y));
    }
};






提供自定义比较器类型

另一种方法是提供自定义比较器类型,而不是依赖 std :: less< Point> 。这样的最大优点是能够定义多个可能含义不同的事物,并根据需要在容器或算法中使用它们。

Another method would be to provide a custom comparator type rather than relying on std::less<Point>. The biggest advantage in this is the ability to define several that can mean different things, and use them in containers or algorithms as appropriately needed.

struct CmpPoint
{
    bool operator()(const Point& lhs, const Point& rhs) const
    {
        return (lhs.x < rhs.x) || ((!(rhs.x < lhs.x)) && (lhs.y < rhs.y));
    }
};

这样,您现在就可以声明 std :: set 像这样:

With that, you can now declare your std::set like this:

std::set<Point,CmpPoint> mySet;

此方法需要考虑的事项:类型不属于 Point ,因此对访问私有成员变量或函数的任何访问都必须通过以来访者身份进行交友来解决。

Something to consider with this approach: The type is not part of Point, so any access to private member variables or functions has to be accounted for via friending in come capacity.

提供自由功能运算符<

Provide a free-function operator <

另一种较不常见的机制只是提供了提供操作符< 的全局自由功能。这不是成员函数。再次执行此操作,默认的 std :: less< Point> 将产生有效的代码。

Another less common mechanism is simply provide a global free-function that provides operator <. This is NOT a member function. In doing this, once again, the default std::less<Point> will result in valid code.

bool operator <(const Point& lhs, const Point& rhs)
{
    return (lhs.x < rhs.x) || ((!(rhs.x < lhs.x)) && (lhs.y < rhs.y));
}

这似乎是自定义比较器和成员运算符的混合,并且的确有很多优点和缺点。例如:像成员 operator< 一样,您可以使用默认的 std :: less< Point> 。与自定义比较器一样,这是一个非类函数,因此必须通过朋友或访问者才能访问私有成员。

This may seem a mix of both the custom comparator and the member operator, and indeed many of the pros and cons of each come along. Ex: like the member operator <, you can just use the default std::less<Point>. Like the custom comparator, this is a non-class function, so access to private members must be provided via friending or accessors.

摘要

对于您的需求,我会采用简单的方法;只需使成员 operator< 。您总是有可能希望以此方式订购积分。如果不是,请使用自定义比较器。在 情况下,请确保 sure 严格严格的排序。

For your needs, I'd go with the simple approach; just make a member operator <. Chances are you'll always want to order your Points in that fashion. If not, go with the custom comparator. In either case make sure you honor strict weak ordering.

这篇关于如何创建结构的std :: set?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆