2

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);
}
9
  • What do you mean example 2 does not work? It can work with right type of calling. See a live demo. Commented Apr 28, 2020 at 11:44
  • void test_ptr(int const* const& p) would be the correct signature for 2. The pointer needs to be const too. Commented Apr 28, 2020 at 11:46
  • .... and 3 does not work when you pass p to it since int_ptr is non-const. const int_ptr& means int* const& not int const*&. Commented Apr 28, 2020 at 11:53
  • Does this answer your question? Commented Apr 28, 2020 at 12:12
  • 1
    @TedLyngmo Nevermind that. Anyone with a better proposal can throw their suggestion in the ring. Better an imperfect answer than none at all. Thanks for your help. Commented Apr 28, 2020 at 14:44

1 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

2 Comments

That seems to work. I chose to get rid of the typedef since it was not what I wanted to express anyway. Moving the const from before the int_ptr to behind the int_ptr clarified why this was the case. I went with the extra const at the end of your answer, which did the trick for me.
@Cerno Great! I was trying to find the correct passages in the standard to make the answer better by using the words of the standard - but when it comes to this it refers back and forth between different chapters so I found it hard to make it clearer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.