起初我是新来的,英语不是我的母语,所以对任何语法上的失败道歉,但我发现这个社区真的很好,所以我会尽可能准确地问我的问题。
我想将自己的类对象添加到stl容器multiset中,并希望使用我自己在类中定义的重载less运算符对其进行排序。我真的试过几个解决方案,但没有真正有效,所以我希望有人能给我一些有用的提示来解决它。
以下是我对班级定义的总体看法:
class object {
public:
int first;
string second;
object(int f, string s) {
first = f;
second = s;
}
bool operator<(const object &comp) {
return first < comp.first;
}
};
这是我的第一次尝试而且没有用,所以我也尝试将重载的运算符声明为朋友方法,但它也不起作用。
以下是我的主要功能的简短代码摘录:
includes ...
//code omitted
int main() {
multiset<object*> mmset;
mmset.insert(new object(10, "test"));
mmset.insert(new object(11, "test"));
return 0;
}
过了一段时间,我开始调试我的代码,并试图找出问题所在,我遇到了以下让我有点怀疑的事情。
从stl:
中提取代码// TEMPLATE STRUCT less
template<class _Ty>
struct less : public binary_function<_Ty, _Ty, bool>
{ // functor for operator<
bool operator()(const _Ty& _Left, const _Ty& _Right) const
{ // apply operator< to operands
return (_Left < _Right);
}
};
我在这一行设置了一个断点并观察了程序在这里做了什么,我不知道为什么,但它只比较两个对象的地址并返回所以总是假的。尽管运算符存在且_Left和_Right变量包含我的对象的地址,它从不调用我的重载less运算符。
如果有人可以帮助我,我会非常感激。
最好的问候
汤姆
答案 0 :(得分:5)
您没有在object
中存储multiset
。您正在存储object*
s。这些是指向object
的指针。这意味着该集将命令您插入的指针。
看起来你真的只想要一个multiset<object>
:
multiset<object> mmset;
mmset.emplace(10, "test");
mmset.emplace(11, "test");
现在它将使用<
来比较object
s。
如果你真的想存储指针,你需要为multiset
提供一个自定义比较器。在C ++ 11中,您可以使用lambda:
auto f = [](int* a, int* b) { return *a < *b; };
std::multiset<int*, decltype(f)> mmset(f);
Pre-C ++ 11,您可以使用与此lambda函数相同的主体创建一个实现operator()
的函数对象。
答案 1 :(得分:1)
感谢您的帮助。这似乎是解决这个问题的好方法。
我已经在新的C ++ 11标准中进行了更深入的搜索,发现有另一种可能的解决方案可以通过稍微简单的实现解决这个问题,但结果相同:) 我将发布它作为其他寻求者的相同问题的信息。
您可以将任何构造函数传递给stl容器一个所谓的比较对象,容器将使用该对象来排列您的内容。
您唯一要做的就是在类中定义重载的operator()
并将它们“误用”为比较运算符。
class object {
int first;
string second;
object() { };
object(int f, string s) {
first = f;
second = s;
}
bool operator()(const object *comp1, const object *comp2) const {
return comp1->first < comp2->first;
}
}
另外你现在要做的另一件事是将object
作为容器定义中的第二个参数传递:
multiset(object*, object) mmset;
您还可以为此目的使用额外的类进行比较,因为否则您需要一个默认构造函数来以这种方式使用此类。