Почему я получаю ошибку компиляции для этой программы в g ++ 4.8.5? - PullRequest
0 голосов
/ 05 октября 2018

Я пытаюсь решить проблему с онлайн-судьей , и судья использует 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 ]

0 голосов
/ 06 октября 2018

Обратите внимание на эту строку в сообщении об ошибке

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' последний в объявлении функции класса?

0 голосов
/ 06 октября 2018

Да, GCC 4.8 поддерживает большую часть C ++ 11, что можно увидеть здесь .Тем не менее, это, кажется, ошибка в GCC 4.8.Точные требования std::sort приведены в разделе 25.4 этой спецификации ISO от 2013 года.

Там отмечается, что единственным требованием к operator< является то, что он реализует " строгий слабый порядок".Затем он продолжает определять «строгий слабый порядок» по своим математическим свойствам.Ничто из этого не подразумевает, что operator< должен быть константным, как пытался заставить GCC 4.8.operator< может, возможно, изменить внутреннюю переменную и все еще следовать спецификации, если возвращаемые логические значения делают "строгий слабый порядок".Это может быть использовано для подсчета количества сравнений, выполненных для каждой переменной с помощью функции std::sort, что позволяет упростить сравнение std::sort, не вдаваясь в неопределенное поведение (как только один пример множества различных возможностей).

Использование const должно было быть чрезмерным допущением относительно исходной реализации C ++ 11 в GCC 4.8 и было исправлено в более поздних версиях.

К сожалению, если онлайновый судья использует эту версию GCC, вы можетеничего не поделать.Другие ответы здесь определяют, как это исправить (а именно, сделать вашу функцию-член постоянной).

Копаясь в истории GCC, мы видим, что она была изменена здесь , 2013-09-27.Это выглядело как более крупный рефакторинг, который, возможно, не обратил внимания на тонкости, но вкладчик действительно удалил const в нескольких областях, так что это казалось преднамеренным.Сообщение коммита также не слишком поучительно.Если вы хотите, вы можете написать ему, посмотреть, помнит ли он xD

0 голосов
/ 05 октября 2018
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 объекты внутри.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...