Почему я получаю ошибку компиляции для этой программы в g++ 4.8.5?
Я пытаюсь решить проблему от интернет-судьи, и судья использует 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? Как мне скомпилировать это?
3 ответа
Да, GCC 4.8 поддерживает большую часть C++11, что можно увидеть здесь. Тем не менее, это, кажется, ошибка в GCC 4.8. Точные требования std::sort
расположены в разделе 25.4 настоящей спецификации ISO с 2013 года.
Там отмечается, что единственным требованием к operator<
является то, что он реализует " строгий слабый порядок". Затем он продолжает определять "строгий слабый порядок" по своим математическим свойствам. Ничто из этого не означает, что operator<
должно быть const, как GCC 4.8 пытался форсировать. operator<
возможно, может изменить внутреннюю переменную и все еще следовать спецификации, пока возвращаемые логические значения делают "строгий слабый порядок". Это можно использовать для подсчета количества сравнений, сделанных по каждой переменной std::sort
функция, позволяющая облегчить сравнительный анализ std::sort
не вдаваясь в неопределенное поведение (как один из примеров множества разных возможностей).
Использование const должно было переусердствовать в исходной реализации C++ 11 в GCC 4.8 и было исправлено в более поздних версиях.
К сожалению, если онлайн-судья использует эту версию GCC, вы ничего не можете с этим поделать. Другие ответы здесь определяют, как это исправить (а именно, сделать вашу функцию-член const).
Копаясь в истории GCC, мы видим, что она была изменена здесь, 2013-09-27. Это казалось большим рефактором, который, возможно, не обратил внимания на тонкости, но вкладчик действительно удалил const
в нескольких областях, так что это казалось преднамеренным. Сообщение коммита также не слишком поучительно. Если вы хотите, вы можете написать ему, посмотреть, помнит ли он xD
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
объекты внутри больше.
Обратите внимание на эту строку в сообщении об ошибке
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;
}
};
Обратитесь к этой ссылке для получения дополнительной информации: Значение 'const' последний в объявлении функции класса?