Cerno
Cerno

Reputation: 831

Reference to pointer to const as function argument

I have the following base code:

Base Code

int main()
{
  int i = 1;

  const int* p = &i;
  int* q = &i;

  test_ptr(p);
  test_ptr(q);
}

Can anyone explain why the first and third example work with the above base code, but the second one doesn't?

Example Implementation test_ptr()

Example 1 works. This works because function with pointer to const int will also accept a pointer to non-const int (but not the other way around)

void test_ptr(const int* p)  // pointer to const int
{

}

Example 2 doesn't work. I don't really understand why. It is still a pointer to const int, but passed as a reference. This doesn't align with my understanding about how references work. It fails when I pass a non-const pointer to the function.

void test_ptr(const int*& p)  // reference to pointer to const int
{

}

Example 3 works again and I am completely lost. So if case 2 does not work, why does it work again if I express the int* as a typedef?

typedef int* int_ptr;

void test_ptr(const int_ptr& p)  // like case 2 but int* expressed as typedef
{

}

This also happens when I use pointer-to-pointer instead of reference-to-pointer.

Edit: Example 3 needs a different main function to make use of the typedef:

int main()
{
  int i = 1;

  const int_ptr p = &i;  // use typedef here
  int_ptr q = &i;  // use typedef here

  test_ptr(p);
  test_ptr(q);
}

Upvotes: 2

Views: 276

Answers (1)

Ted Lyngmo
Ted Lyngmo

Reputation: 117298

Example 2:

void test_ptr(const int*& p);

This works for const int* but not int* because the conversion from int* to a const int* implies a temporary and binding to a temporary has to be done using a const& for life extension to kick in.

Example 3 (when using the first main version):

typedef int* int_ptr; // or: using int_ptr = int*;

void test_ptr(const int_ptr& p);

This is the same as both of these:

void test_ptr(int_ptr const& p);
void test_ptr(int* const& p);

const is applied to the new type from right to left so it's not the int that is const, it's the pointer. The function will therefore accept int*, but not const int* since the function is allowed to change the int:s according to its signature.

The function that would accept both int* and const int* should have one of these equivalent signatures:

void test_ptr(const int* const& p);
void test_ptr(int const* const& p);

Disclaimer: I'm very unsure about the wording used in this answer

Upvotes: 1

Related Questions