问题
With the following code
void TestF(const double ** testv){;}
void callTest(){
double** test;
TestF(test);
}
I get this:
'TestF' : cannot convert parameter 1 from 'double **' to 'const double **'
I cannot understand why.
Why test cannot be silently casted to const double**?
Why should I do it explicitly? I know that
TestF(const_cast<const double**>(test))
makes my code correct, but I feel this should be unnecessary.
Are there some key concepts about const that I'm missing?
回答1:
The language allows implicit conversion from double ** to const double *const *, but not to const double **. The conversion you attempt would implicitly violate the rules of const correctness, even though it is not immediately obvious.
The example in the [de-facto standard] C++ FAQ illustrates the issue
https://isocpp.org/wiki/faq/const-correctness#constptrptr-conversion
Basically, the rule is: once you add const at some level of indirection, you have to add const to all levels of indirection all the way to the right. For example, int ***** cannot be implicitly converted to int **const ***, but it can be implicitly converted to int **const *const *const *
回答2:
It is correct that a double ** cannot be implicitly converted to a const double **. It can be converted to a const double * const *, though.
Imagine this scenario:
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!
So, if your function does not intend to modify any of the pointers involved, change it to take a const double * const *. If it intends to do modifications, you must decide whether all the modifications it does are safe and thus const_cast can be used, or whether you really need to pass in a const double **.
来源:https://stackoverflow.com/questions/19910296/how-to-convert-pointer-to-pointer-type-to-const