为什么在g ++ 4.8.5中出现此程序的编译错误?

时间:2018-10-05 20:51:45

标签: c++11 g++4.8

我正在尝试通过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?我该如何编译?

3 个答案:

答案 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?