Зачем нужны ссылки на указатели? С++

Наткнулся на вот такой код, который, как я понимаю, создает указатель и ссылку на этот указатель:

int* int_ptr = &x;
int*& strange_ref = int_ptr;

Отсюда вопрос, зачем в С++ вообще существует подобный синтаксис, ведь strange_ref, несмотря на то, что является типом int*&, все равно будет иметь такой же функционал, как и int*. Все также можно будет разыменовать эту ссылку и тд. Почему этот синтаксис вообще существует и где он применяется?


Ответы (4 шт):

Автор решения: HolyBlackCat

несмотря на то, что является типом int*&, все равно будет иметь такой же функционал, как и int*

А вот и нет.

int x = 1, y = 2;
int *a = &x;
int *b = a;
int *&c = a;
a = &y;
std::cout << *b << '\n'; // 1
std::cout << *c << '\n'; // 2
→ Ссылка
Автор решения: user7860670

Ну вот конкретный практический пример: типичная функция навроде swap без проблем работает с указателями, принимая их по ссылке, как и другие объекты:

template<typename T>
void swap(T & left, T & right)
{
    T tmp{left};
    left = right;
    right = tmp;
}

Или несколько операций с предварительно выбранным одним указателем:

int * p1{};
int * p2{};
int * & pcur{cond ? p1 : p2};
... // много операций, изменяющих pcur;

Собственно указатели являются такими же объектами, как и все остальные, и для них можно использовать все те же сценарии работы со ссылками.

→ Ссылка
Автор решения: Тарас Атавин

Ссылка на указатель оправдана, например, если она параметр функции или операнд перегруженного оператора. Да, эта ссылка имеет синтаксис не целевой величины, а указателя. Но если функция должна не взять готовый указатель у вызывающего кода, а вернуть его в вызывающий код, но сделать это через параметр, то по указателю это сделать нельзя, так как он указывает на целевую величину, а не на указатель.



    size_t f(int *p)
    {
     size_t s;
     s=(512+((rand())% 1024));
     p=new int [s];
     return s;
    }
    int main ()
    {
     int *x;
     int *y;
     f(x);
     return 0;
    }

Здесь p – указатель не на x, а на память, выделенную оператором new. А где лежит x? Функции надо знать именно это, только тогда она сможет положить в этот x указатель на память, выделенную оператором new. Куда класть адрес выделенной памяти? В x? Или в y?



    size_t f(int *&p)
    {
     size_t s;
     s=(512+((rand())% 1024));
     p=new int [s];
     return s;
    }
    int main ()
    {
     int *x;
     int *y;
     f(x);
     delete [] x;
     return 0;
    }

А вот здесь всё в порядке, p – ссылка на x, теперь можно в этот x положить значение, возвращённое оператором new. А вот x уже будет указателем на память, выделенную по new. Или Вы не это имели ввиду?

→ Ссылка
Автор решения: Коля Иванцов

Могу дополнить уже данные ответы своей интерпретацией. Возможно кому-то так будет проще разобраться.

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

→ Ссылка