【问题标题】:STL Sort on nested Classes嵌套类的 STL 排序
【发布时间】:2011-09-26 19:00:18
【问题描述】:

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

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

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

我有

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

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

在我的节点类中,我有

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

但它给了我错误。如何在我的节点类中构造 operator&lt; 函数以使用 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

【问题讨论】:

  • 什么错误?这将有助于诊断。
  • 在您的问题中包含错误消息被认为是一种很好的做法

标签: c++ stl graph operator-overloading


【解决方案1】:

你的成员函数需要const-qualified:

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 Node >' as 'this' 'bool Node::operator丢弃限定符

我已经突出显示了有启发性的部分。这告诉我,在 OP 的实际代码中,由于代码的构造方式(可能 sort 调用本身在 const 成员函数中?谁知道......)this 指针必须是 const,但是从operator&lt;的张贴声明中我们可以看出,方法不是const。编译器错误中提到的“限定符”是标准所称的“cv-qualifiers”。 “cv”代表“const/volatile”。

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

“你说 X 是 const,但你试图通过 const X 调用非 const 成员函数。为了让我进行这个调用,我必须丢弃 X 上的 const 限定符。我不允许这样做,所以你必须修复你的代码。”

这里被“丢弃”的限定词是方法本身的限定词。换句话说,operator&lt; 必须是 const 成员函数,但不是。

【讨论】:

  • 我确实看到了这个错误并修复了它,但它仍然出错(见上文)但我将 const 添加到函数的末尾,它现在可以工作了:D 谢谢
  • 您能否添加更多详细信息,为什么使 operator &lt; const 可以解决问题?谢谢
  • @Anibus:完成。希望对您有所帮助。
【解决方案2】:
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>());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-11-28
    • 2018-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-10
    • 2020-09-18
    相关资源
    最近更新 更多