Есть такой код (ничего не делает, приведён просто для примера):
#include <iostream>
using namespace std;
int f(const int *)
{
return 0;
}
int main()
{
int * x = new int;
f(x);
getchar();
return 0;
}
Здесь (в коде выше) всё работает.
Но в таком коде:
#include <iostream>
using namespace std;
int f(const int **) // Добавил ещё одну *
{
return 0;
}
int main()
{
int * x = new int;
f(&x); // Теперь передаю адрес указателя
getchar();
return 0;
}
Visual Studio выдаёт ошибку:
"int f(const int **)": невозможно преобразовать аргумент 1 из "int**"
в "const int **"
Не пойму, в чём принципиальная разница между int* и int**. Почему одно преобразовывается без проблем, а другое нет?
Это сделано для избегания потенциального неявного присвоения исходному указателю указателя на неизменяемый объект минуя const_cast:
int const val{};
int * p_val;
p_val = &val; // не прокатывает
int const * * pp_val{&p_val}; // предположим что эта строка работает
*pp_val = &val; // исходный указатель теперь тоже указывает на неизменяемый объект val
*p_val = 42;
Чтобы заработал исходный пример достаточно будет добавить еще один const квалификатор.
int f(int const * const *)
Преобразование int * * в int const * const * будет разрешено так как оно не создает описанную выше проблему:
int const * const * pp_val{&p_val}; // работает
*pp_val = &val; // не прокатывает
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости