对嵌套类进行 STL 排序
我有一个具有节点向量的图类。每个节点都有一个顶点和一个 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
I have a graph class that has a vector of nodes. In each node, there is a vertex and a STL list of edges. Essentially it's an adjacency list.
For my assignment, I am trying to display the vertices with the most edges. I figured I would sort the graph's vector of nodes by edge size and print the top N vertices.
So I am trying to figure out STL sort, but I'm having difficulties.
I have
std::sort(path.begin(), path.end());
Where path is the vector of nodes (node = vertex value and list of edges)
In my node class, I have
bool operator<(const Node<T>& rhs){
return size < rhs.size; //size is how many edges the vertex has
}
But it's giving me errors. How can I construct the operator<
function in my node class to work with STL sort?
Here are the errors:
$ 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
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您的成员函数需要是 const 限定的:
编辑
根据请求,这里有更多我知道您需要使成员函数成为 const 的信息。
挖掘与 stdlib 相关的编译器错误中隐藏的含义是一门艺术,并且通过练习可以变得更好。与 Stdlib 相关的错误通常会引发一系列编译器错误。通常,这些错误中最有用的是最后一个错误,因为该错误是从您实际编写的代码的上下文中生成的,而不是来自库代码的内部。
在这种情况下,最后一个编译器错误是:
我已经突出显示了有启发性的部分。这告诉我,在 OP 的实际代码中,由于代码的构造方式(也许
sort
调用本身位于const
成员函数中?谁知道......)this
指针必须是const
,但从发布的operator<
声明中可以看出,该方法不是const
代码>.编译器错误中提到的“限定符”是标准所说的“cv 限定符”。 “cv”代表“常量/易失性”。当编译器说“将
const X
作为this
传递给Node::operator<
丢弃限定符”时,它真正想说的是:“你说
X
是 const,但随后您尝试通过const X
调用非常量成员函数。为了让我进行此调用,我必须。丢弃constX
上的限定符不允许我这样做,所以你必须修复你的代码。”这里“丢弃”的限定符是方法本身的限定符。换句话说,
operator<
必须是 const 成员函数,但事实并非如此。Your member function needs to be
const
-qualified:EDIT
Per request, here is a bit more how I knew that you needed to make the member function
const
.Divining the hidden meanings in stdlib-related compiler errors is something of an art, and something that you get better at with practice. Stdlib-related errors will often emit a whole series of compiler errors. Usually the most useful of these errors is the last one, because that one is generated from the context of the code you actually wrote, rather than coming from the bowels of the library code.
In this case, the last compiler error was:
I've highlighted the illuminating bits. This tells me that in OP's actual code, because of how the code is constructed (maybe the
sort
call is itself in aconst
member function? who knows...) thethis
pointer must beconst
, but as we can see from the posted declaration ofoperator<
, the method is notconst
. The "qualifiers" referred to in the compiler errors are what the Standard calls "cv-qualifiers". "cv" stands for "const/volatile."When the compiler says "Passing
const X
asthis
toNode::operator<
discards qualifiers" what it's really trying to say is:"You said
X
was const but then you tried to call a non-const member function throughconst X
. In order for me to make this call, I would have to discard the const qualifier onX
. I'm not allowed to do that, so you have to fix your code."The qualifiers being "discarded" here are the qualifiers on the method itself. In other words,
operator<
must be a const member function, but it's not.将运算符设置为 const 可能有助于不激怒编译器。
注意:出现问题的原因是
this
始终是const
,因此编译器希望您承诺不更改您通过使用this
创建方法指定的值> 具有const
限定符。或者,您可以进行非成员比较以与排序一起使用,如下所示:
Making the operator
const
as it should be may help with not angering the compiler.Note: The problem arises because
this
is alwaysconst
so the compiler expects you to promise not to change it which you specify by making the method usingthis
to have theconst
qualifier.Alternately you could make a non-member comparison for use with sort like so: