2

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".

andreasdr
  • 3,804
  • 4
  • 28
  • 32
  • 3
    `const double*&` means "reference to `const double*`". You already know what the latter means because you just described it: it means that although the pointer can be modified, the thing pointed-to cannot be. – M.M May 03 '16 at 13:56
  • Possible duplicate of [void ( \*( \*f\[\] ) () ) ()](http://stackoverflow.com/questions/34548762/void-f) – AliciaBytes May 03 '16 at 13:57
  • 3
    Also: [cdecl.org](http://www.cdecl.org) is good if one is uncertain about the meaning of a declaration. – AliciaBytes May 03 '16 at 14:06

3 Answers3

4

const double*& is a reference to a pointer to a const double. So *x is a const double, which you cannot assign thus. const is attached to double here.

You may want to use either double* const (which is a const pointer to [non-const] double) or double* const& (which is a reference to a const pointer to [non-const] double).

shrike
  • 4,449
  • 2
  • 22
  • 38
3
const double*& x

means that x is a reference to a pointer to a const double, which implies the object can't be modified (i.e. const is a type qualifier attached to double, not the pointer object itself in this case)

ad3angel1s
  • 484
  • 1
  • 5
  • 17
  • Thanks for the answer, I suspected as much. But what confuses me is that while `const double*&` is a reference to a pointer to a const double, `const double&` is NOT a reference to a const double. How can this be understood? In terms of the clockwise-spiral rule? Something else? – andreasdr May 03 '16 at 14:04
  • 1
    @andreasdr `const double&` IS a reference to a const double. – AliciaBytes May 03 '16 at 14:05
  • I'm starting to realize what my misunderstanding has been. Thanks! – andreasdr May 03 '16 at 14:08
2

const double*& x, means a non-const reference to const double*.

When you pass a double*, it need to be casted to const double*, which is a temporary variable and can't be bound to a non-const reference, that's why compiler complains.

BTW: const double* const & x is a const reference to const double*.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405
  • Thanks, but regarding your last point, isn't that a reference to a const pointer to a const double? Although figuring out what `const` "sticks to" confuses me to no end, that is the interpretation suggested by http://cdecl.org/ – andreasdr May 03 '16 at 14:22
  • 1
    @andreasdr Yes, the precise statement should be "reference to const pointer to const double". Since there's no "non-const reference", which could be rebound to something else after initialized, so we say "const reference" for "reference to const" and "non-const reference" for "reference to non-const". Yes it's confusing... – songyuanyao May 03 '16 at 14:28