为什么这个程序在 g++ 4.8.5 中会出现编译错误?
Why do I get a compilation error for this program in g++ 4.8.5?
我正在尝试解决 online judge 的问题,法官使用 g++ 4.8.5。
以下程序在我的机器 (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)
^
法官用-std=c++11 -O2 -lm
编译。
g++ 4.8 不完全支持 C++11 吗?我该如何编译它?
const bool operator<(const Task &o) {
应该是
bool operator<(const Task &o) const {
return的值为const
没有意义,作为比较运算符不需要修改*this
.
错误消息显示 passing 'const Task' as 'this' argument of 'const bool Task::operator<(const Task&)' discards qualifiers
,因此在 std::sort
的内部某处它试图在 const Task
对象上调用 operator<
。您原来的 tasks
数组不是 const
,所以这大概是因为 std::sort
正在调用一个带有 const Task &
的辅助函数(因为辅助函数不需要修改任何东西)。
调用失败,因为您的 operator<
未声明为 const
(即可在 const
对象上调用)。
我不确定 g++ 8.2 有什么不同,但显然 std::sort
的实现已经改变,所以它不再在内部引用 const T
对象。
注意错误消息中的这一行
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;
}
};
有关详细信息,请参阅此 link:Meaning of 'const' last in a function declaration of a class?
是的,GCC 4.8 确实支持 C++11 的大部分,从 2013 年可以看出 here. However, this seems to have been an error in GCC 4.8. The exact requirements of std::sort
are located in Section 25.4 of this ISO specification。
它注意到 operator<
的唯一要求是它实现了“strict weak ordering”。然后它继续通过其数学属性定义 "strict weak ordering"。 None 这似乎意味着 operator<
必须是常量,因为 GCC 4.8 试图强制。 operator<
可能会更改内部变量,并且仍然遵循规范,只要返回的布尔值构成 "strict weak ordering"。这可用于计算 std::sort
函数对每个变量进行的比较次数,从而允许更轻松地对 std::sort
进行基准测试,而不会出现未定义的行为(作为许多不同可能性的一个示例)。
使用 const 肯定是对 GCC 4.8 中 C++11 的原始实现的过度假设,并在以后的版本中得到纠正。
不幸的是,如果在线判断使用的是那个版本的GCC,你也无能为力。这里的其他答案指定了如何修复它(即,使您的成员函数为 const)。
深入研究 GCC 的历史,我们可以看到它在 2013 年 9 月 27 日被更改 here。这似乎是一个更大的重构,可能没有注意错综复杂的地方,但贡献者确实在几个方面删除了 const
,所以它似乎是有意的。提交消息也不太有启发性。如果你愿意你可以给他发邮件,看看他是否记得 xD
我正在尝试解决 online judge 的问题,法官使用 g++ 4.8.5。
以下程序在我的机器 (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)
^
法官用-std=c++11 -O2 -lm
编译。
g++ 4.8 不完全支持 C++11 吗?我该如何编译它?
const bool operator<(const Task &o) {
应该是
bool operator<(const Task &o) const {
return的值为const
没有意义,作为比较运算符不需要修改*this
.
错误消息显示 passing 'const Task' as 'this' argument of 'const bool Task::operator<(const Task&)' discards qualifiers
,因此在 std::sort
的内部某处它试图在 const Task
对象上调用 operator<
。您原来的 tasks
数组不是 const
,所以这大概是因为 std::sort
正在调用一个带有 const Task &
的辅助函数(因为辅助函数不需要修改任何东西)。
调用失败,因为您的 operator<
未声明为 const
(即可在 const
对象上调用)。
我不确定 g++ 8.2 有什么不同,但显然 std::sort
的实现已经改变,所以它不再在内部引用 const T
对象。
注意错误消息中的这一行
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;
}
};
有关详细信息,请参阅此 link:Meaning of 'const' last in a function declaration of a class?
是的,GCC 4.8 确实支持 C++11 的大部分,从 2013 年可以看出 here. However, this seems to have been an error in GCC 4.8. The exact requirements of std::sort
are located in Section 25.4 of this ISO specification。
它注意到 operator<
的唯一要求是它实现了“strict weak ordering”。然后它继续通过其数学属性定义 "strict weak ordering"。 None 这似乎意味着 operator<
必须是常量,因为 GCC 4.8 试图强制。 operator<
可能会更改内部变量,并且仍然遵循规范,只要返回的布尔值构成 "strict weak ordering"。这可用于计算 std::sort
函数对每个变量进行的比较次数,从而允许更轻松地对 std::sort
进行基准测试,而不会出现未定义的行为(作为许多不同可能性的一个示例)。
使用 const 肯定是对 GCC 4.8 中 C++11 的原始实现的过度假设,并在以后的版本中得到纠正。
不幸的是,如果在线判断使用的是那个版本的GCC,你也无能为力。这里的其他答案指定了如何修复它(即,使您的成员函数为 const)。
深入研究 GCC 的历史,我们可以看到它在 2013 年 9 月 27 日被更改 here。这似乎是一个更大的重构,可能没有注意错综复杂的地方,但贡献者确实在几个方面删除了 const
,所以它似乎是有意的。提交消息也不太有启发性。如果你愿意你可以给他发邮件,看看他是否记得 xD