Перенос константных указателей в std :: stackвыдает ошибку компиляции - PullRequest
0 голосов
/ 11 февраля 2019

Приведенный ниже код приводит к следующей ошибке компиляции:

error: no matching member function for call to 'push' 
st.push(ptr);

Проблема исчезнет, ​​если я удалю const для параметра ptr в func.Так что это означает, что вы не можете поместить постоянный указатель в стек.Почему это так?Это также выдает ту же ошибку, если я пытаюсь вставить ее в std::queue, и я подозреваю, что другие контейнеры также.

#include <iostream>
#include <stack>

void func(const int *&ptr)
{
   std::stack<int *> st;
   st.push(ptr);
}

int main(int argc, char const *argv[])
{    
   int i = 2;
   auto ptr = &i;
   func(ptr);
}

Ответы [ 2 ]

0 голосов
/ 11 февраля 2019

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

Если вы можете преобразовать const int* в int* при перемещении указателя на стек, вы можете затем изменить объект, выдвинув неконстантный указатель.Вот почему этот код не компилируется.

Решение состоит в том, чтобы сделать стек набором константных указателей

void func(const int *&ptr)
{
   std::stack<const int *> st;
   st.push(ptr);
}

Теперь этого недостаточно: ваша проблема переместит сообщение об ошибке вызывающей стороне.Вы можете решить это:

int main(int argc, char const *argv[])
{    
   int i = 2;
   const int* ptr = &i;   // <------ not auto
   func(ptr);
}

Почему?Потому что функция ожидает ссылку на константный указатель в качестве параметра.Передача нормального указателя ptr не позволяет создать ссылку на указатель const.

Если вы передадите указатель по значению, а не по ссылке, он будет работать независимо от того, является ли ptr константным или нет, поскольку компилятору разрешено неявно преобразовывать значение неконстантного указателя в константное.

0 голосов
/ 11 февраля 2019

Сделать в стеке const int *:

void func(const int *&ptr)
{
   std::stack<const int *> st;  // <== Add const before int * here.
   st.push(ptr);
}

Объяснение:

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

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

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

Другими словами: вы всегда можете добавить const по пути, но вы никогда не сможете (*) удалить его снова.

(*) Вы можете удалить const, применив заклинание, но выдолжен делать это, только если вы точно знаете, что делаете.Обычно в этом нет необходимости.

...