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

查看:12
本文介绍了如何创建 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.0VCincludexfunctional(125): error C2784: bool std::operator <(const std::vector<_Ty,_Ax> &;,const std::vector<_Ty,_Ax> &): 未能将参数带入模板const std::vector<_Ty,_Ax>&"来自const点"

1>C:Program Files (x86)Microsoft Visual Studio 10.0VCincludexfunctional(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.0VCincludexfunctional(125): error C2676: binary<":const Point"没有定义这个操作符或转换为集成运算符可接受的类型

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

如何编译我的代码?

推荐答案

std::set 模板提供了一个关联容器,其中包含一组排序的唯一对象.那里的关键词是排序独特.为了支持排序,许多可能性随之而来,但最终所有的可能性都必须导致符合 strict weak订购.

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 的第二个模板参数是 comparison 类型.默认值 std::less 由标准库提供,其中 Key 是您存储在容器中的对象类型(在您的情况下, ).该默认值仅使用支持密钥类型的任何允许的可用 operator < 生成比较.这意味着一种或另一种方式,如果您使用默认比较器(在您的情况下为 std::less),那么您的类必须假设如下操作:

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 <

到目前为止,最简单的方法是为您的 Point 类提供一个成员 operator <.这样做 pt1 变得有效并且 std::less 然后很高兴.假设您的类是传统的 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.这方面的最大优势是能够定义几个可能意味着不同事物的东西,并根据需要在容器或算法中使用它们.

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.

提供一个自由函数operator <

另一种不太常见的机制是简单地提供一个全局自由函数,该函数提供 operator <.这不是成员函数.再次执行此操作时,默认的 std::less 将生成有效代码.

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.与自定义比较器一样,这是一个非类函数,因此必须通过友元或访问器提供对私有成员的访问.

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 <.您可能总是希望以这种方式订购您的 Point.如果没有,请使用自定义比较器.在任一情况下,请确保遵守严格的弱排序.

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天全站免登陆