Ссылка на указатель на const в качестве аргумента функции - PullRequest
2 голосов
/ 28 апреля 2020

У меня есть следующий базовый код:

Базовый код

int main()
{
  int i = 1;

  const int* p = &i;
  int* q = &i;

  test_ptr(p);
  test_ptr(q);
}

Может кто-нибудь объяснить, почему первый и третий примеры работают с вышеуказанным базовым кодом, но второй нет?

Пример реализации test_ptr()

Пример 1 работает. Это работает, потому что функция с указателем на const int также будет принимать указатель на неконстантное int (но не наоборот)

void test_ptr(const int* p)  // pointer to const int
{

}

Пример 2 не работает. Я не очень понимаю, почему. Это все еще указатель на const int, но переданный как ссылка. Это не согласуется с моим пониманием того, как работают ссылки. Сбой, когда я передаю неконстантный указатель на функцию.

void test_ptr(const int*& p)  // reference to pointer to const int
{

}

Пример 3 снова работает, и я полностью потерялся. Так что, если случай 2 не работает, почему он работает снова, если я express int * как typedef?

typedef int* int_ptr;

void test_ptr(const int_ptr& p)  // like case 2 but int* expressed as typedef
{

}

Это также происходит, когда я использую указатель на указатель вместо ссылки на -pointer.

Редактировать: В примере 3 требуется другая основная функция для использования typedef:

int main()
{
  int i = 1;

  const int_ptr p = &i;  // use typedef here
  int_ptr q = &i;  // use typedef here

  test_ptr(p);
  test_ptr(q);
}

1 Ответ

1 голос
/ 28 апреля 2020

Пример 2:

void test_ptr(const int*& p);

Это работает для const int*, но не для int*, потому что преобразование из int* в const int* подразумевает временное и привязку к временному необходимо сделать использование const& для увеличения продолжительности жизни.

Пример 3 (при использовании первой версии main):

typedef int* int_ptr; // or: using int_ptr = int*;

void test_ptr(const int_ptr& p);

Это то же самое, что оба из них:

void test_ptr(int_ptr const& p);
void test_ptr(int* const& p);

const применяется к новому типу справа налево, поэтому это не int, а const, это указатель. Поэтому функция будет принимать int*, но не const int*, поскольку функции разрешено изменять int: s в соответствии с ее сигнатурой.

Функция, которая будет принимать как int*, так и const int* должна иметь одну из этих эквивалентных подписей:

void test_ptr(const int* const& p);
void test_ptr(int const* const& p);

Отказ от ответственности: я очень не уверен в формулировке, использованной в этом ответе

...