«Этот» аргумент функции-члена «выбрать» имеет тип «константный SelectParam», но функция не помечена как константная

Я пытаюсь вызвать функцию для полиморфного элемента. Но я получаю следующее сообщение об ошибке во время компиляции:

'this' argument to member function 'select' has type 'const SelectParam', but function is not marked const

ошибка отображается при p->selection(*it)

std::set<Tuple>::iterator it;
for (it = tuples.begin(); it != tuples.end();) {
    for (const SelectParam* p: selectionParams) {
        bool successful = p->select(*it);
        if ( !successful ) {
            it = tuples.erase(it);
        } else {
            it++;
        }
    }
}

и вот как определяются эти классы. (Раньше у меня не было всех констант и &, но я помещал их везде, где мог, в надежде, что я сделаю все, что мне нужно, константой, но ясно, что я неправильно подхожу к проблеме, поскольку это ничего не меняет.

В одном из дочерних классов, который хранится по родительскому указателю.

bool const select(Tuple const & tup) {
    bool matched = false;
    if (tup[idx] == val) {
        matched = true;
    }
    return matched;
}

В другом дочернем классе, который используется с полиморфизмом

bool const select(Tuple const & tup) {
    bool matched = false;
    if (tup[idx1] == tup[idx2]) {
        matched = true;
    }
    return matched;
}

И, наконец, вот супер простой родительский класс.

class SelectParam {
    public:
    virtual const bool select( Tuple const & t) = 0;
};

Заранее спасибо за желание помочь моему слабому мозгу.

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
0
21 209
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вам нужно явно указать компилятору, что ваша функция не будет изменять никаких членов:

bool const select(Tuple const & tup) const {
Ответ принят как подходящий

Действительно, вы не можете назвать не-const метод const объектом. Но вы также не можете вызвать метод, отличный от const, через указатель или ссылка к объекту const (независимо от того, является ли упомянутый объект const или нет).

Это означает, что это:

const SelectParam* ptr = whatever();
ptr->select(someTuple);

плохо сформирован.

В вашем случае вы объявили указатель на const SelectParam здесь, в этой строке:

for (const SelectParam* p: selectionParams) {

Просто уберите const и все должно заработать :-)

С другой стороны, если select никогда не предназначено для изменения объекта, просто пометьте его как const:

virtual const bool select( Tuple const & t) const = 0;

И ваш код тоже должен работать.

Объект, объявленный как const, не может быть изменен ни const, ни функцией-членом non-const (за исключением конструктора и деструктора). Даже если он передается по ссылке. Из этого правила есть два исключения:

  1. const-ность можно отбросить (отбросить константу), но обычно это не рекомендуется.
  2. Члены класса могут быть объявлены с помощью ключевого слова mutable. Эти члены могут быть изменены с помощью функций-членов, даже если содержащий объект объявлен const.

Подробнее можно прочитать здесь:

const object - an object whose type is const-qualified, or a non-mutable subobject of a const object. Such object cannot be modified: attempt to do so directly is a compile-time error, and attempt to do so indirectly (e.g., by modifying the const object through a reference or pointer to non-const type) results in undefined behavior.

Как прокомментировали другие, одним из решений было бы добавить ключевое слово const к функции-члену как в ее объявлении а также, так и в определении. При этом функцию можно вызывать даже на const объектах.

А что не так с this?

Внутри функции-члена this — это указатель на текущий объект, для которого была вызвана функция [видеть].

Другие вопросы по теме