Reputation: 831
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
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