Well... this is how I think it works (I admit I get confused over this too).
The problem is how C resolves the type. Even though logically inserting MyKey* between the const and the & looks like it has become the subject of a const& it doesn't quite work that way.
What happens is that the const latches on to the * changing the semantics. If you went through a typedef you could avoid that:
1 2 3
|
typedef MyKey* MyKeyPtr;
find(const MyKeyPtr& myKey); // works fine
|
But without the typedef, the introduction of the * symbol causes the const to apply to it rather than the &.
The way to spell out to the compiler that you want the const to remain on the & rather than the * is:
|
find(MyKey* const& myKey); // works fine
|
The thing to remember is that it doesn't matter which side of the identifier the const goes but it does matter which side of the * or & it goes.
So to make the pointer or reference const you can do:
1 2 3
|
const MyKey* mp1; // these two...
MyKey const* mp2; // ...are the same
|
Same thing with reference:
1 2 3
|
const MyKey& mr1; // these two...
MyKey const& mr2; // ...are the same
|
But when you want a reference to a pointer:
Choosing which one is const is more tricky. Making the pointer const is easy because it is closest to the identifier:
1 2 3
|
const MyKey*& mpr1; // these two...
MyKey const*& mpr2; // ...are the same
|
But making the reference const is harder because you only have one option available to you:
Its all down to order of precedence which is designed to allow the programmer to express all possible combinations of constness.
(hopefully I didn't make any errors in that explanation)