Because converting Foo** → const Foo** would be invalid and dangerous.
C++ allows the (safe) conversion Foo* → Foo const*, but gives an error if you try to implicitly convert Foo** → const Foo**.
The rationale for why that error is a good thing is given below. But first, here is the most common solution: simply change const Foo** to const Foo* const*:
class Foo { /* ... */ };void f(const Foo** p);void g(const Foo* const* p);int main(){Foo** p = /*...*/;// ...f(p); // ERROR: it's illegal and immoral to convert Foo** to const Foo**g(p); // Okay: it's legal and moral to convert Foo** to const Foo* const*// ...}
The reason the conversion from Foo** → const Foo** is dangerous is that it would let you silently and accidentally modify a const Foo object without a cast:
class Foo {public:void modify(); // make some modification to the this object};int main(){const Foo x;Foo* p;const Foo** q = &p; // q now points to p; this is (fortunately!) an error*q = &x; // p now points to xp->modify(); // Ouch: modifies a const Foo!!// ...}
If the q = &p line were legal, q would be pointing at p. The next line, *q = &x, changes p itself (since *q is p) to point at x. That would be a bad thing, since we would have lost the const qualifier: p is a Foo* but x is a const Foo. The p->modify() line exploits p’s ability to modify its referent, which is the real problem, since we ended up modifying a const Foo.
By way of analogy, if you hide a criminal under a lawful disguise, he can then exploit the trust given to that disguise. That’s bad.
浙公网安备 33010602011771号