Как преобразовать "указатель на тип указателя" в const?
Со следующим кодом
void TestF(const double ** testv){;}
void callTest(){
double** test;
TestF(test);
}
Я получаю это:
'TestF' : cannot convert parameter 1 from 'double **' to 'const double **'
Я не понимаю, почему.
Почему test
не может быть беззвучно нажата на const double**
?
Почему я должен делать это явно? Я знаю, что
TestF(const_cast<const double**>(test))
делает мой код правильным, но я считаю, что это не нужно.
Есть ли какие-то ключевые понятия о const, которые мне не хватает?
Ответы
Ответ 1
Язык позволяет неявное преобразование от double **
до const double *const *
, но не к const double **
. Преобразование, которое вы пытаетесь, будет неявно нарушать правила корректности const, даже если это не сразу очевидно.
Пример в стандарте [de facto standard] С++ иллюстрирует проблему
http://www.parashift.com/c++-faq/constptrptr-conversion.html
В принципе, правило: после добавления const
на некоторый уровень косвенности, вы должны добавить const
на все уровни косвенности до упора вправо. Например, int *****
не может быть неявно преобразован в int **const ***
, но он может быть неявно преобразован в int **const *const *const *
Ответ 2
Верно, что a double **
не может быть неявно преобразован в const double **
. Однако он может быть преобразован в const double * const *
.
Представьте себе этот сценарий:
const double cd = 7.0;
double d = 4.0;
double *pd = &d;
double **ppd = &pd;
const double **ppCd = ppd; //this is illegal, but if it were possible:
*ppCd = &cd; //now *ppCd, which is also *ppd, which is pd, points to cd
*pd = 3.14; // pd now points to cd and thus modifies a const value!
Итак, если ваша функция не намерена изменять какой-либо из указателей, измените ее, чтобы взять const double * const *
. Если он намеревается внести изменения, вы должны решить, безопасны ли все его модификации и, следовательно, const_cast
, или вам действительно нужно передать const double **
.