Consider the following code:
void func1(const double& x) {
    x = 1.2; //compilation error! (assignment of read-only reference)
}
void func2(const double* x) {
    *x = 1.3; //compilation error! (assignment of read-only location)
}
void func3(const double*& x) {
    *x = 1.4; //compilation error! (assignment of read-only location)
}
int main()
{
    double a = 1.1;
    func1(a);
    double *y = &a;
    func2(y);
    func3(y); //compilation error! (invalid initialization of reference of type 'const double*&' from expression of type 'double*')
    return 0;
}
Here, my understanding is that func1() takes a reference to a double, and that func2() takes a pointer to a double. In both cases, the const keyword means that the value of the double can't be modified by the function. Hence, I get compilation errors as expected.
But what's going on with func3()? I can't seem to find an explanation for what this input argument type means that would explain the compilation errors. I would assume that const double*& x means "a reference to a double*, which can't be modified". But this seems to be the wrong interpretation: I can't send in a double* (but I CAN send in a const double*) and I can modify the address that the pointer points to (but I CAN'T modify the double that the pointer points to).
I guess my confusion comes from a misunderstanding of what the const keyword is "attached" to: to the &? to the double*? What is the interpretation of const double*& x that would clear up my confusion?
EDIT: This question is distinct from the suggested duplicate because it in large part has to do with how to interpret what the const keyword "attaches to".
 
     
     
    