简体   繁体   English

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

[英]Why do I get a compilation error for this program in g++ 4.8.5?

I'm trying to solve a problem from an online judge and the judge uses g++ 4.8.5. 我正在尝试解决在线法官的问题,该法官使用g ++ 4.8.5。

The following program compiles correctly on my machine (g++ 8.2.0) with -std=c++11 -pedantic-errors : 以下程序在我的计算机(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);
}

However, the judge gives me the following errors: 但是,法官给我以下错误:

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)
       ^

The judge compiles with -std=c++11 -O2 -lm . 法官使用-std=c++11 -O2 -lm编译。

Does g++ 4.8 not fully support C++11? g ++ 4.8是否不完全支持C ++ 11? How do I compile this? 我该如何编译?

const bool operator<(const Task &o) {

should be 应该

bool operator<(const Task &o) const {

It doesn't make sense for the return value to be const , and as a comparison operator it doesn't need to modify *this . 返回值是const是没有意义的,作为比较运算符,它不需要修改*this

The error message says passing 'const Task' as 'this' argument of 'const bool Task::operator<(const Task&)' discards qualifiers , so somewhere in the bowels of std::sort it's trying to call operator< on a const Task object. 错误消息说passing 'const Task' as 'this' argument of 'const bool Task::operator<(const Task&)' discards qualifiers ,因此在std::sort肠子中某处试图在const Task上调用operator< const Task对象。 Your original tasks array is not const , so this is presumably because std::sort is calling a helper function that takes a const Task & (because the helper function doesn't need to modify anything). 您原始的tasks数组不是const ,所以大概是因为std::sort正在调用一个带有const Task &的辅助函数(因为该辅助函数不需要修改任何内容)。

The call fails because your operator< wasn't declared as const (ie callable on a const object). 调用失败,因为没有将您的operator<声明为const (即可在const对象上调用)。

I'm not sure what's different about g++ 8.2, but apparently the implementation of std::sort has changed so it doesn't refer to const T objects internally anymore. 我不确定g ++ 8.2的区别是什么,但是显然std::sort的实现已更改,因此它不再在内部引用const T对象。

Yes, GCC 4.8 does support most of C++11, which can be seen here . 是的,GCC 4.8确实支持大多数C ++ 11,可以在此处看到。 However, this seems to have been an error in GCC 4.8. 但是,这似乎是GCC 4.8中的错误。 The exact requirements of std::sort are located in Section 25.4 of this ISO specification from 2013. 从2013年开始, std::sort的确切要求位于此ISO规范的 25.4节中。

There it notes that the only requirement on operator< is that it implements a " strict weak ordering ". 在此指出,对operator<的唯一要求是它实现了“ 严格弱排序 ”。 It then goes on to define a "strict weak ordering" by its mathematical properties. 然后,继续通过其数学属性定义“严格弱排序”。 None of this seems to imply that operator< must be const as GCC 4.8 tried to force. 这似乎并不意味着operator<必须是GCC 4.8试图强制使用的常量。 The operator< could perhaps change an internal variable, and still follow the specification, as long as the booleans returned make a "strict weak ordering". 只要返回的布尔值进行“严格弱排序”, operator<也许可以更改内部变量,并且仍然遵循规范。 This could be used to count the number of comparisons made on each variable by the std::sort function, allowing easier benchmarking of std::sort without going into undefined behavior (As just one example of many different possibilities). 这可以用于计算std::sort函数对每个变量进行的比较次数,从而可以更轻松地对std::sort进行基准测试,而不会发生未定义的行为(仅是许多不同可能性的一个示例)。

Using const must have been an over-assumption on the original implementation of C++11 in GCC 4.8, and was corrected in later versions. 在GCC 4.8中使用const一定是对C ++ 11的原始实现的过度假设,并且在更高版本中已得到纠正。

Unfortunately, if the online judge is using that version of GCC, you can't do anything about it. 不幸的是,如果在线法官正在使用该版本的GCC,您将无能为力。 The other answers here specify how to fix it (Namely, making your member function const). 此处的其他答案指定了解决方法(即,使成员函数为const)。

Digging into GCC's history, we can see that it was changed here , on 2013-09-27. 深入研究GCC的历史,我们可以看到它 2013年9月27日被更改。 It seemed like a larger refactor that might not've paid attention to intricacies, but the contributer did remove const in several areas so it appeared to be intentional. 似乎是一个较大的重构,可能没有注意复杂性,但是贡献者确实在多个区域删除了const ,因此这似乎是有意的。 The commit msg isn't too enlightening either. 提交消息也不是很有启发性。 If you want you can email him, see if he remembers xD 如果您希望可以给他发送电子邮件,请查看他是否还记得xD

Notice this line in the error message 注意错误消息中的这一行

error: passing 'const Task' as 'this' argument of 'const bool Task::operator<(const Task&)' discards qualifiers

std::sort expects the operator< for your object to not modify the object itself. std::sort期望对象的operator<不会修改对象本身。 You need to indicate the fact that your comparison operator does not mutate the object's state by explicitly marking it as const . 您需要通过将对象显式标记为const来表明比较运算符不会改变对象的状态这一事实。

The correct version would look something like 正确的版本看起来像

struct Task {
    int deadline;
    const bool operator<(const Task &o) const {
        return deadline < o.deadline;
    }
};

Refer to this link for more info: Meaning of 'const' last in a function declaration of a class? 有关更多信息,请参见此链接: 类的函数声明中'const'最后的含义?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM