STL 对嵌套类进行排序

STL Sort on nested Classes

本文关键字:排序 嵌套 STL      更新时间:2023-10-16

我有一个具有节点向量的图类。在每个节点中,都有一个顶点和一个边的 STL 列表。本质上,它是一个邻接列表。

对于我的任务,我正在尝试显示具有最多边缘的顶点。我想我会按边缘大小对图形的节点向量进行排序,并打印前 N 个顶点。

所以我试图弄清楚 STL 排序,但我遇到了困难。

我有

 std::sort(path.begin(), path.end());

其中路径是节点的向量(节点 = 顶点值和边列表(

在我的节点类中,我有

bool operator<(const Node<T>& rhs){
    return size < rhs.size; //size is how many edges the vertex has
}

但它给了我错误。如何在节点类中构造 operator< 函数以使用 STL 排序?

以下是错误:

$ make
g++ -c -g -std=c++0x graphBuilder.cpp
In file included from /usr/lib/gcc/i486-slackware-linux/4.5.2/../../../../include/c++/4.5.2/algorithm:63:0,
             from graph.h:6,
             from graphBuilder.cpp:2:
/usr/lib/gcc/i486-slackware-linux/4.5.2/../../../../include/c++/4.5.2/bits/stl_algo.h: In function '_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, const _Tp&) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Node<std::basic_string<char> >*, std::vector<Node<std::basic_string<char> >, std::allocator<Node<std::basic_string<char> > > > >, _Tp = Node<std::basic_string<char> >]':
/usr/lib/gcc/i486-slackware-linux/4.5.2/../../../../include/c++/4.5.2/bits/stl_algo.h:2249:70:   instantiated from '_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Node<std::basic_string<char> >*, std::vector<Node<std::basic_string<char> >, std::allocator<Node<std::basic_string<char> > > > >]'
/usr/lib/gcc/i486-slackware-linux/4.5.2/../../../../include/c++/4.5.2/bits/stl_algo.h:2280:54:   instantiated from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Node<std::basic_string<char> >*, std::vector<Node<std::basic_string<char> >, std::allocator<Node<std::basic_string<char> > > > >, _Size = int]'
/usr/lib/gcc/i486-slackware-linux/4.5.2/../../../../include/c++/4.5.2/bits/stl_algo.h:5212:4:   instantiated from 'void std::sort(_RAIter, _RAIter) [with _RAIter = __gnu_cxx::__normal_iterator<Node<std::basic_string<char> >*, std::vector<Node<std::basic_string<char> >, std::allocator<Node<std::basic_string<char> > > > >]'
graph.h:32:13:   instantiated from 'void Graph<T>::topN(int) [with T = std::basic_string<char>]'
graphBuilder.cpp:10:17:   instantiated from here /usr/lib/gcc/i486-slackware-linux/4.5.2/../../../../include/c++/4.5.2/bits/stl_algo.h:2211:4: error: passing 'const Node<std::basic_string<char> >' as 'this' argument of 'bool Node<T>::operator<(const Node<T>&) [with T = std::basic_string<char>]' discards qualifiers
make: *** [graphBuilder.o] Error 1

您的成员函数需要const限定:

bool operator<(const Node<T>& rhs) const{

编辑

根据请求,这里有更多我如何知道您需要使成员函数const.

在与 stdlib 相关的编译器错误中占卜隐藏的含义是一门艺术,并且通过练习可以做得更好。 与 Stdlib 相关的错误通常会发出一系列编译器错误。 通常,这些错误中最有用的是最后一个错误,因为该错误是从您实际编写的代码的上下文中生成的,而不是来自库代码的内部。

在本例中,最后一个编译器错误是:

graphBuilder.cpp:10:17:从这里实例化 /usr/lib/gcc/i486-slackware-linux/4.5.2/../../../../include/c++/4.5.2/bits/stl_algo.h:2211:4: 错误:将"const 节点>">传递为"this"> 'bool Node::operator<(const Node&( 的参数 [与 T = std::basic_string]' 丢弃限定符

我已经突出显示了具有启发性的部分。 这告诉我,在OP的实际代码中,由于代码的构造方式(也许sort调用本身在const成员函数中? 谁知道...this指针必须是const的,但是从operator<的声明中我们可以看出,该方法并不const。 编译器错误中提到的"限定符"就是标准中所说的"cv-限定符"。 "cv"代表"常量/挥发性"。

当编译器说"将const X作为this传递给Node::operator<丢弃限定符"时,它真正想说的是:

"你说X是常量,但后来你试图通过const X调用一个非常量成员函数。 为了让我做出这个调用,我将不得不丢弃 X 上的常量限定符。 我不允许这样做,所以你必须修复你的代码。

这里被"丢弃"的限定符是方法本身的限定符。 换句话说,operator<必须是 const 成员函数,但事实并非如此。

bool operator<(const Node<T>& rhs) const {
    return size() < rhs.size();
}

使运算符按原样const可能有助于不激怒编译器。

注意:出现此问题是因为this始终const因此编译器希望您承诺不更改它,通过使用this使方法具有const限定符来指定它。

或者,您可以进行非成员比较以用于排序,如下所示:

<template typename T>
struct CompareNodes {
bool operator()(const Node<T>& lhs, const Node<T>& rhs) const
{
     return lhs.size() < rhs.size();
}
};
std::sort(path.cbegin(), path.cend(), CompareNodes<T>());