我正在尝试通过online judge解决问题,法官使用的是g ++ 4.8.5。
以下程序使用duration < 0
在我的计算机(g ++ 8.2.0)上正确编译:
-std=c++11 -pedantic-errors
但是,法官给我以下错误:
#include <algorithm>
struct Task {
int deadline;
const bool operator<(const Task &o) {
return deadline < o.deadline;
}
};
Task tasks[] = {8, 4, 3, 5, 1, 2, 0, 7};
int main()
{
std::sort(tasks, tasks + 8);
}
法官以In file included from /usr/include/c++/4.8/algorithm:62:0,
from Main.cpp:1:
/usr/include/c++/4.8/bits/stl_algo.h: In instantiation of '_RandomAccessIterator std::__unguarded_partition(_RandomAccessIterator, _RandomAccessIterator, const _Tp&) [with _RandomAccessIterator = Task*; _Tp = Task]':
/usr/include/c++/4.8/bits/stl_algo.h:2283:70: required from '_RandomAccessIterator std::__unguarded_partition_pivot(_RandomAccessIterator, _RandomAccessIterator) [with _RandomAccessIterator = Task*]' /usr/include/c++/4.8/bits/stl_algo.h:2315:54:
required from 'void std::__introsort_loop(_RandomAccessIterator, _RandomAccessIterator, _Size) [with _RandomAccessIterator = Task*; _Size = int]' /usr/include/c++/4.8/bits/stl_algo.h:5461:36:
required from 'void std::sort(_RAIter, _RAIter) [with _RAIter = Task*]' Main.cpp:15:23:
required from here /usr/include/c++/4.8/bits/stl_algo.h:2245:19:
error: passing 'const Task' as 'this' argument of 'const bool Task::operator<(const Task&)' discards qualifiers [-fpermissive]
while (__pivot < *__last)
^
进行编译。
g ++ 4.8是否不完全支持C ++ 11?我该如何编译?
答案 0 :(得分:3)
const bool operator<(const Task &o) {
应该是
bool operator<(const Task &o) const {
返回值const
毫无意义,作为比较运算符,它不需要修改*this
。
错误消息显示passing 'const Task' as 'this' argument of 'const bool Task::operator<(const Task&)' discards qualifiers
,因此在std::sort
肠内某个地方,它试图在operator<
对象上调用const Task
。您原始的tasks
数组不是const
,所以大概是因为std::sort
正在调用一个使用const Task &
的辅助函数(因为该辅助函数不需要修改任何东西)。
由于未将您的operator<
声明为const
(即可以在const
对象上调用),因此呼叫失败。
我不确定g ++ 8.2的区别是什么,但是显然std::sort
的实现已更改,因此它不再在内部引用const T
对象。
答案 1 :(得分:3)
是的,GCC 4.8确实支持大多数C ++ 11,可以here看到。但是,这似乎是GCC 4.8中的错误。 std::sort
的确切要求位于此ISO specification自2013年起的第25.4节中。
它注意到,对operator<
的唯一要求是它实现了一个“ strict weak ordering”。然后,继续通过其数学属性定义“严格弱排序”。这似乎并不意味着operator<
必须是常量,因为GCC 4.8试图强制使用。 operator<
可能会更改内部变量,并且仍然遵循规范,只要返回的布尔值具有“严格弱排序”即可。这可以用来计算std::sort
函数对每个变量进行比较的次数,从而可以更容易地对std::sort
进行基准测试,而不会发生未定义的行为(仅是许多不同可能性的一个例子)。>
使用const一定是对GCC 4.8中C ++ 11的原始实现的过度假设,并且在更高版本中已得到纠正。
不幸的是,如果在线法官正在使用该版本的GCC,您将无能为力。此处的其他答案指定了解决方法(即,使成员函数为const)。
深入研究GCC的历史,我们可以看到它在here于2013-09-27进行了更改。看起来好像是一个较大的重构,可能没有注意复杂性,但是贡献者确实在几个区域中删除了const
,因此这似乎是有意的。提交消息也不是很有启发性。如果您愿意,可以给他发送电子邮件,看看他是否记得xD
答案 2 :(得分:1)
在错误消息中注意这一行
error: passing 'const Task' as 'this' argument of 'const bool Task::operator<(const Task&)' discards qualifiers
std::sort
期望对象的operator<
不会修改对象本身。您需要通过将对象显式标记为const
来表明比较运算符不会改变对象的状态。
正确的版本看起来像
struct Task {
int deadline;
const bool operator<(const Task &o) const {
return deadline < o.deadline;
}
};
有关更多信息,请参见此链接:Meaning of 'const' last in a function declaration of a class?