6
int val2 = 38;
int *ptr = &val2;
const int *&ptrRef = ptr; // ERROR

int i = 92;
int &ref_i = i;
const int &ref_i2 = ref_i;  // OK

Why I can't have a const reference that references to a non-const pointer? I thought that if you access the const ptrRef identifier, it will treat val2 as const. When you access ptr, it will treat val2 as non-const. This works for the bottom part of the code, so I don't understand why it won't work for pointers.

cigien
  • 57,834
  • 11
  • 73
  • 112
Goddrew
  • 125
  • 2
  • 5

2 Answers2

7

East-const makes it clearer:

int const * & ptrRef = ptr; // ERROR

It's the pointer that is const. However, ptr is a different type. You can't bind a reference to a different type. It requires a conversion, making the initializer a temporary (ptr converted to int const*).

Now, there's a more confusing catch: const references can bind to temporaries, extending their lifetime: Why do const references extend the lifetime of rvalues?

They e.g. allow funtions to take arguments by const& and still be callable with temporaries:

void foo(std::string const&);

foo("foor"s+"bar"s); // still ok
sehe
  • 374,641
  • 47
  • 450
  • 633
4

I think, your question boils to a simple typo. If you want a const reference to non-const pointer, use following:

int* const&  ptrRef = ptr; // no error

This declares ptrRef as a const reference to non-const pointer. Another, perhaps cleaner option, is to introduce a typedef:

 using intptr = int *;
 const intptr& ptrRef = ptr;

Additionally, you can get out of business of manually specifying the type altogether:

const auto&  ptrRef = ptr; // no error

And, for good measure, this would work (as in compile) too, if that is what you want:

const int* const&  ptrRef = ptr; // no error

The latest bit declares constant reference to a constant pointer.

SergeyA
  • 61,605
  • 5
  • 78
  • 137
  • 2
    `int* const& ptrRef = ptr;` is a "non-const reference to a const `int*` pointer", not a "const reference to a non-const `int*` pointer", like you claim. `const` applies to the thing on its left (in this case, the `int*` pointer), unless there is nothing there then it applies to the thing on its right instead. In `const int *&ptrRef = ptr;`, the `const` applies to the `int`being pointed at, not to the `int*` pointer. – Remy Lebeau Jul 08 '20 at 18:01