3

起初我是新来的,英语不是我的母语,所以对任何语法错误表示歉意,但我发现这个社区真的很好,所以我会尽可能准确地提出我的问题。

我想将我自己的类对象添加到一个 stl 容器多重集中,并想用我自己在我的类中定义的重载的 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 运算符。

如果有人可以帮助我,我将不胜感激。

最好的问候

汤姆

4

2 回答 2

5

您没有将objects 存储在multiset. 您正在存储object*s。这些是指向objects 的指针。这意味着该集合将对您插入其中的指针进行排序。

看起来你真的只是想要一个multiset<object>

multiset<object> mmset;
mmset.emplace(10, "test");
mmset.emplace(11, "test");

现在它将<用于比较objects 本身。

如果您真的想存储指针,则需要为multiset. 在 C++11 中,您可以使用 lambda 轻松完成此操作:

auto f = [](int* a, int* b) { return *a < *b; };
std::multiset<int*, decltype(f)> mmset(f);

在 C++11 之前,您可以创建一个operator()与此 lambda 函数具有相同主体的函数对象。

于 2013-05-11T13:08:54.580 回答
2

谢谢您的帮助。这似乎是解决这个问题的好方法。

我在新的 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;

您也可以为此目的使用一个额外的类来进行比较,否则您需要一个默认构造函数才能以这种方式使用此类。

于 2013-05-11T14:46:58.753 回答