Со следующим кодом
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 что мне не хватает?
Язык допускает неявное преобразование из double **
в const double *const *
, но не для const double **
, Попытка преобразования, которую вы пытаетесь, неявно нарушает правила правильности const, даже если это не сразу очевидно.
Пример в [стандарте де-факто] C ++ FAQ иллюстрирует проблему
https://isocpp.org/wiki/faq/const-correctness#constptrptr-conversion
В принципе, правило таково: после добавления const
на некотором уровне косвенности, вы должны добавить const
до всех уровней косвенности вплоть до правой. Например, int *****
не может быть неявно преобразовано в int **const ***
, но это может быть неявно преобразовано в int **const *const *const *
Это правильно, что 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 **
,