Dmi*_*rii 5 c++ containers struct stl set
我需要创建stl :: set结构.我写
stl::set <Point> mySet; // Point - name of the structure.
Run Code Online (Sandbox Code Playgroud)
但后来我尝试向mySet添加一个结构实例
Point myPoint;
mySet.insert(myPoint);
Run Code Online (Sandbox Code Playgroud)
有几个编译错误(错误C2784,错误C2676).有人可以给个建议吗?
1> C:\ Program Files(x86)\ Microsoft Visual Studio 10.0\VC\include\xfunctional(125):错误C2784:bool std :: operator <(const std :: vector <_Ty,_Ax>&,const std: :vector <_Ty,_Ax>&):无法将参数带到模板"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"未定义此运算符或转换为可接受的类型综合运营商
该std::set
模板提供了一个关联容器,其中包含一组有序的唯一对象.关键词有分类和独特.为了支持排序,随之而来的是一些可能性,但最终所有这些都必须导致符合严格的弱排序.
第二个模板参数std::set
是比较类型.默认值std::less<Key>
由标准库提供,其中Key
是您在容器中存储的对象类型(在您的情况下Point
).该默认值仅使用operator <
支持密钥类型的任何可用可用来生成比较.这意味着这种或那种方式,如果您使用默认比较器(std::less<Point>
在您的情况下),那么您的类必须假设这样的操作:
Point pt1(args);
Point pt2(args);
if (pt1 < pt2) // <<=== this operation
dosomething();
Run Code Online (Sandbox Code Playgroud)
执行此操作的多种方法如下所示:
提供会员 operator <
到目前为止,实现此目的的最简单方法是operator <
为您的Point
班级提供成员.这样做pt1 < pt2
变得有效,std::less<Point>
然后开心.假设你的类是传统的x,y点,它看起来像这样:
struct Point
{
int x,y;
// compare for order.
bool operator <(const Point& pt) const
{
return (x < pt.x) || ((!(pt.x < x)) && (y < pt.y));
}
};
Run Code Online (Sandbox Code Playgroud)
提供自定义比较器类型
另一种方法是提供自定义比较器类型而不是依赖std::less<Point>
.这方面的最大优点是能够定义几个可能意味着不同的东西,并在容器或算法中使用它们作为适当的需要.
struct CmpPoint
{
bool operator()(const Point& lhs, const Point& rhs) const
{
return (lhs.x < rhs.x) || ((!(rhs.x < lhs.x)) && (lhs.y < rhs.y));
}
};
Run Code Online (Sandbox Code Playgroud)
有了它,你现在可以声明你std::set
喜欢这样:
std::set<Point,CmpPoint> mySet;
Run Code Online (Sandbox Code Playgroud)
使用这种方法需要考虑的事项:类型不是其中的一部分Point
,因此任何对私有成员变量或函数的访问都必须通过友好关系来计算.
提供免费功能 operator <
另一种不太常见的机制是简单地提供提供的全局自由功能operator <
.这不是会员功能.在这样做时,再一次,默认std::less<Point>
将导致有效的代码.
bool operator <(const Point& lhs, const Point& rhs)
{
return (lhs.x < rhs.x) || ((!(rhs.x < lhs.x)) && (lhs.y < rhs.y));
}
Run Code Online (Sandbox Code Playgroud)
这似乎是自定义比较器和成员操作员的混合,实际上每个都有许多优点和缺点.例如:与会员一样operator <
,您可以使用默认值std::less<Point>
.与自定义比较器一样,这是一个非类功能,因此必须通过友情或访问者提供对私人成员的访问.
摘要
为了您的需要,我会采用简单的方法; 只是成为一名成员operator <
.您可能总是希望以Point
这种方式订购您的产品.如果没有,请使用自定义比较器.在任何情况下,使确保你的荣誉严格弱序.
为了扩展WhozCraig 的回答,从C++11 开始,您还可以使用lambda 表达式而不是定义比较对象。对于以下代码中的 lambda 表达式,我还假设您的Point
类仅由x
和y
成员组成:
auto comp = [](const Point& p1, const Point& p2) {
return p1.x < p2.x || (p1.x == p2.x && p1.y < p2.y);
};
std::set<Point, decltype(comp)> mySet(comp);
Point myPoint;
mySet.insert(myPoint);
Run Code Online (Sandbox Code Playgroud)
至于 WhozCraig 给出的解,也comp
必须满足严格的弱排序条件。
归档时间: |
|
查看次数: |
5549 次 |
最近记录: |